feat(core): 实现用户积分计算逻辑

- 新增积分规则处理模块
- 集成积分计算到相关业务流程中

fix(file): 修复上传工具中路径乱码和非法字符问题

- 使用 UTF-8 编码统一路径解析
- 增加路径合法性校验

fix(user): 修正用户 Passkey 生成与验证流程

- 修复部分场景下 Passkey 未生成的问题
- 调整 Passkey 校验逻辑,确保唯一性和安全性

Change-Id: Id5eacb20f354a07de01413474095c2b2b9b49231
diff --git a/react-ui/src/pages/Peer/index.tsx b/react-ui/src/pages/Peer/index.tsx
new file mode 100644
index 0000000..dec06ca
--- /dev/null
+++ b/react-ui/src/pages/Peer/index.tsx
@@ -0,0 +1,60 @@
+import React, { useEffect, useState } from 'react';
+import { Table, Spin, Alert } from 'antd';
+import {listBtTorrentPeers} from "@/pages/Peer/service";
+import {BtTorrentPeer} from "@/pages/Peer/data";
+
+
+interface PeerTableProps {
+  torrentId: number;
+}
+
+const PeerTable: React.FC<PeerTableProps> = ({ torrentId }) => {
+  const [loading, setLoading] = useState<boolean>(false);
+  const [peers, setPeers] = useState<BtTorrentPeer[]>([]);
+  const [error, setError] = useState<string | null>(null);
+
+  useEffect(() => {
+    const fetchPeers = async () => {
+      setLoading(true);
+      try {
+        const data = await listBtTorrentPeers();
+
+        setPeers(data.rows);
+      } catch (err) {
+        setError('Failed to load peer data.');
+      } finally {
+        setLoading(false);
+      }
+    };
+
+    fetchPeers();
+  }, [torrentId]);
+
+  const columns = [
+    { title: 'Peer Key', dataIndex: 'peerKey', key: 'peerKey' },
+    { title: 'IP Address', dataIndex: 'ip', key: 'ip' },
+    { title: 'Port', dataIndex: 'port', key: 'port' },
+    { title: 'Uploaded', dataIndex: 'uploaded', key: 'uploaded' },
+    { title: 'Downloaded', dataIndex: 'downloaded', key: 'downloaded' },
+    { title: 'Left', dataIndex: 'left', key: 'left' },
+    { title: 'Last Seen', dataIndex: 'lastSeen', key: 'lastSeen' },
+  ];
+
+  return (
+    <div>
+      {error && <Alert message={error} type="error" />}
+      {loading ? (
+        <Spin size="large" />
+      ) : (
+        <Table<BtTorrentPeer>
+          columns={columns}
+          dataSource={peers}
+          rowKey="peerKey"
+          pagination={false}
+        />
+      )}
+    </div>
+  );
+};
+
+export default PeerTable;