新增邀请码页面,新增添加好友功能

Change-Id: Ifa0a5c355ab3693eecfe919de06fa9bef8171695
diff --git a/react-ui/src/pages/Invite/data.d.ts b/react-ui/src/pages/Invite/data.d.ts
new file mode 100644
index 0000000..2a07e7a
--- /dev/null
+++ b/react-ui/src/pages/Invite/data.d.ts
@@ -0,0 +1,12 @@
+// data.ts 建议的类型定义
+export interface GetInviteCodeResponse {
+    code: number;
+    msg: string;
+    data: string; // 邀请码字符串
+}
+
+export interface GetUserByInviteCodeResponse {
+    code: number;
+    msg: string;
+    data: number; // 用户ID
+}
\ No newline at end of file
diff --git a/react-ui/src/pages/Invite/index.tsx b/react-ui/src/pages/Invite/index.tsx
new file mode 100644
index 0000000..56989ff
--- /dev/null
+++ b/react-ui/src/pages/Invite/index.tsx
@@ -0,0 +1,300 @@
+import React, { useState, useEffect } from 'react';
+import { useModel } from 'umi';
+import { Card, Input, Button, Space, Typography, Row, Col, message } from 'antd';
+import { CopyOutlined, UserAddOutlined, GiftOutlined, ShareAltOutlined } from '@ant-design/icons';
+import { getUserInviteCode, getUserByInviteCode } from './service';
+
+const { Title, Text, Paragraph } = Typography;
+
+const InvitePage: React.FC = () => {
+    const [myInviteCode, setMyInviteCode] = useState<string>('');
+    const [inputInviteCode, setInputInviteCode] = useState<string>('');
+    const [loading, setLoading] = useState<boolean>(false);
+    const [submitting, setSubmitting] = useState<boolean>(false);
+
+    // 获取当前用户信息
+    const { initialState } = useModel('@@initialState');
+    const userId = initialState?.currentUser?.userId || '';
+
+    // 获取我的邀请码
+    const fetchMyInviteCode = async () => {
+        if (!userId) {
+            message.error('用户信息获取失败');
+            return;
+        }
+
+        setLoading(true);
+        try {
+            const response = await getUserInviteCode();
+            if (response.code === 200) {
+                // 根据后端返回的数据结构调整
+                setMyInviteCode(response.msg);
+            } else {
+                message.error(response.msg || '获取邀请码失败');
+            }
+        } catch (error) {
+            message.error('获取邀请码失败');
+        } finally {
+            setLoading(false);
+        }
+    };
+
+    // 复制邀请码
+    const copyInviteCode = () => {
+        if (myInviteCode) {
+            navigator.clipboard.writeText(myInviteCode).then(() => {
+                message.success('邀请码已复制到剪贴板');
+            }).catch(() => {
+                message.error('复制失败,请手动复制');
+            });
+        }
+    };
+
+    // 查询邀请码对应的用户
+    const handleSubmitInviteCode = async () => {
+        if (!inputInviteCode.trim()) {
+            message.warning('请输入邀请码');
+            return;
+        }
+
+        setSubmitting(true);
+        try {
+            const response = await getUserByInviteCode(inputInviteCode.trim());
+
+            if (response.code === 200) {
+                message.success(`邀请码有效,对应用户ID: ${response.data}`);
+                setInputInviteCode('');
+                // 这里可以根据业务需求进行后续操作,比如关注用户等
+            } else {
+                message.error(response.msg || '邀请码无效');
+            }
+        } catch (error) {
+            message.error('查询邀请码失败');
+        } finally {
+            setSubmitting(false);
+        }
+    };
+
+    useEffect(() => {
+        fetchMyInviteCode();
+    }, []);
+
+    return (
+        <div
+            style={{
+                padding: '32px 24px',
+                maxWidth: '800px',
+                margin: '0 auto',
+                minHeight: '100vh',
+                background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
+            }}
+        >
+            {/* 头部标题区域 */}
+            <div style={{ textAlign: 'center', marginBottom: '40px' }}>
+                <GiftOutlined
+                    style={{
+                        fontSize: '48px',
+                        color: '#fff',
+                        marginBottom: '16px',
+                        filter: 'drop-shadow(0 4px 8px rgba(0,0,0,0.2))'
+                    }}
+                />
+                <Title
+                    level={1}
+                    style={{
+                        color: '#fff',
+                        margin: 0,
+                        fontSize: '32px',
+                        fontWeight: 600,
+                        textShadow: '0 2px 4px rgba(0,0,0,0.3)'
+                    }}
+                >
+                    邀请码管理
+                </Title>
+                <Paragraph
+                    style={{
+                        color: 'rgba(255,255,255,0.8)',
+                        fontSize: '16px',
+                        margin: '8px 0 0 0'
+                    }}
+                >
+                    邀请好友,共享美好体验
+                </Paragraph>
+            </div>
+
+            <Row gutter={[24, 24]}>
+                {/* 我的邀请码 */}
+                <Col xs={24} lg={12}>
+                    <Card
+                        title={
+                            <Space>
+                                <ShareAltOutlined style={{ color: '#1890ff' }} />
+                                <span style={{ color: '#1890ff', fontWeight: 600 }}>我的邀请码</span>
+                            </Space>
+                        }
+                        style={{
+                            height: '100%',
+                            borderRadius: '16px',
+                            boxShadow: '0 8px 32px rgba(0,0,0,0.12)',
+                            border: 'none',
+                            background: 'rgba(255,255,255,0.95)',
+                            backdropFilter: 'blur(10px)'
+                        }}
+                        bodyStyle={{ padding: '24px' }}
+                    >
+                        <Space direction="vertical" style={{ width: '100%' }} size="large">
+                            <div style={{
+                                padding: '20px',
+                                background: 'linear-gradient(135deg, #e3f2fd 0%, #f3e5f5 100%)',
+                                borderRadius: '12px',
+                                textAlign: 'center'
+                            }}>
+                                <Text
+                                    type="secondary"
+                                    style={{
+                                        fontSize: '14px',
+                                        display: 'block',
+                                        marginBottom: '16px'
+                                    }}
+                                >
+                                    分享下方邀请码给好友,邀请他们加入
+                                </Text>
+                                <div style={{
+                                    background: '#fff',
+                                    padding: '16px',
+                                    borderRadius: '8px',
+                                    border: '2px dashed #d9d9d9',
+                                    marginBottom: '16px'
+                                }}>
+                                    <Text
+                                        copyable={false}
+                                        style={{
+                                            fontSize: '24px',
+                                            fontWeight: 'bold',
+                                            color: '#1890ff',
+                                            fontFamily: 'Monaco, monospace',
+                                            letterSpacing: '2px'
+                                        }}
+                                    >
+                                        {loading ? '加载中...' : (myInviteCode || '暂无邀请码')}
+                                    </Text>
+                                </div>
+                                <Button
+                                    type="primary"
+                                    size="large"
+                                    icon={<CopyOutlined />}
+                                    onClick={copyInviteCode}
+                                    disabled={!myInviteCode}
+                                    style={{
+                                        borderRadius: '8px',
+                                        height: '44px',
+                                        fontSize: '16px',
+                                        fontWeight: 500,
+                                        boxShadow: '0 4px 12px rgba(24, 144, 255, 0.3)'
+                                    }}
+                                    block
+                                >
+                                    复制邀请码
+                                </Button>
+                            </div>
+                        </Space>
+                    </Card>
+                </Col>
+
+                {/* 输入邀请码 */}
+                <Col xs={24} lg={12}>
+                    <Card
+                        title={
+                            <Space>
+                                <UserAddOutlined style={{ color: '#52c41a' }} />
+                                <span style={{ color: '#52c41a', fontWeight: 600 }}>查询邀请码</span>
+                            </Space>
+                        }
+                        style={{
+                            height: '100%',
+                            borderRadius: '16px',
+                            boxShadow: '0 8px 32px rgba(0,0,0,0.12)',
+                            border: 'none',
+                            background: 'rgba(255,255,255,0.95)',
+                            backdropFilter: 'blur(10px)'
+                        }}
+                        bodyStyle={{ padding: '24px' }}
+                    >
+                        <Space direction="vertical" style={{ width: '100%' }} size="large">
+                            <div style={{
+                                padding: '20px',
+                                background: 'linear-gradient(135deg, #f6ffed 0%, #e6f7ff 100%)',
+                                borderRadius: '12px'
+                            }}>
+                                <Text
+                                    type="secondary"
+                                    style={{
+                                        fontSize: '14px',
+                                        display: 'block',
+                                        marginBottom: '20px',
+                                        textAlign: 'center'
+                                    }}
+                                >
+                                    输入邀请码
+                                </Text>
+                                <Space direction="vertical" style={{ width: '100%' }} size="middle">
+                                    <Input
+                                        value={inputInviteCode}
+                                        onChange={(e) => setInputInviteCode(e.target.value)}
+                                        placeholder="请输入邀请码"
+                                        size="large"
+                                        style={{
+                                            borderRadius: '8px',
+                                            fontSize: '16px',
+                                            height: '48px',
+                                            textAlign: 'center',
+                                            fontFamily: 'Monaco, monospace',
+                                            letterSpacing: '1px'
+                                        }}
+                                        onPressEnter={handleSubmitInviteCode}
+                                    />
+                                    <Button
+                                        type="primary"
+                                        size="large"
+                                        icon={<UserAddOutlined />}
+                                        onClick={handleSubmitInviteCode}
+                                        loading={submitting}
+                                        disabled={!inputInviteCode.trim()}
+                                        style={{
+                                            borderRadius: '8px',
+                                            height: '44px',
+                                            fontSize: '16px',
+                                            fontWeight: 500,
+                                            background: '#52c41a',
+                                            borderColor: '#52c41a',
+                                            boxShadow: '0 4px 12px rgba(82, 196, 26, 0.3)'
+                                        }}
+                                        block
+                                    >
+                                        邀请码
+                                    </Button>
+                                </Space>
+                            </div>
+                        </Space>
+                    </Card>
+                </Col>
+            </Row>
+
+            {/* 底部装饰 */}
+            <div style={{
+                textAlign: 'center',
+                marginTop: '40px',
+                padding: '20px',
+                background: 'rgba(255,255,255,0.1)',
+                borderRadius: '12px',
+                backdropFilter: 'blur(10px)'
+            }}>
+                <Text style={{ color: 'rgba(255,255,255,0.7)', fontSize: '14px' }}>
+                    通过邀请码连接更多朋友,一起享受精彩体验
+                </Text>
+            </div>
+        </div>
+    );
+};
+
+export default InvitePage;
\ No newline at end of file
diff --git a/react-ui/src/pages/Invite/service.ts b/react-ui/src/pages/Invite/service.ts
new file mode 100644
index 0000000..e6cf9af
--- /dev/null
+++ b/react-ui/src/pages/Invite/service.ts
@@ -0,0 +1,19 @@
+import { request } from '@umijs/max';
+import type {
+    GetInviteCodeResponse,
+    GetUserByInviteCodeResponse
+} from './data';
+
+// 获取用户邀请码
+export async function getUserInviteCode(): Promise<GetInviteCodeResponse> {
+    return request('/api/system/user/invite/code', {
+        method: 'GET',  // 修改为 GET 请求
+    });
+}
+
+// 根据邀请码获取用户信息
+export async function getUserByInviteCode(code: string): Promise<GetUserByInviteCodeResponse> {
+    return request(`/api/system/user/invite/user/${code}`, {
+        method: 'GET',  // 修改为 GET 请求,并使用路径参数
+    });
+}
\ No newline at end of file