diff --git a/package.json b/package.json
index 641778e..0eb6789 100644
--- a/package.json
+++ b/package.json
@@ -10,24 +10,25 @@
"preview": "vite preview"
},
"dependencies": {
+ "@ant-design/icons": "^5.2.6",
+ "@monaco-editor/react": "^4.6.0",
+ "@supabase/supabase-js": "^2.38.4",
+ "antd": "^5.11.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
- "antd": "^5.11.0",
- "@ant-design/icons": "^5.2.6",
"react-router-dom": "^6.18.0",
- "@supabase/supabase-js": "^2.38.4",
- "styled-components": "^6.1.0",
- "recharts": "^2.9.0"
+ "recharts": "^2.9.0",
+ "styled-components": "^6.1.0"
},
"devDependencies": {
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@vitejs/plugin-react": "^4.0.3",
+ "autoprefixer": "^10.4.16",
"eslint": "^8.45.0",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
- "autoprefixer": "^10.4.16",
"postcss": "^8.4.31",
"sass": "^1.69.5",
"tailwindcss": "^3.3.5",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index fc78b56..c131343 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -11,6 +11,9 @@ importers:
'@ant-design/icons':
specifier: ^5.2.6
version: 5.5.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@monaco-editor/react':
+ specifier: ^4.6.0
+ version: 4.6.0(monaco-editor@0.52.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@supabase/supabase-js':
specifier: ^2.38.4
version: 2.47.7
@@ -401,6 +404,18 @@ packages:
'@jridgewell/trace-mapping@0.3.25':
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
+ '@monaco-editor/loader@1.4.0':
+ resolution: {integrity: sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==}
+ peerDependencies:
+ monaco-editor: '>= 0.21.0 < 1'
+
+ '@monaco-editor/react@4.6.0':
+ resolution: {integrity: sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==}
+ peerDependencies:
+ monaco-editor: '>= 0.25.0 < 1'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+
'@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
@@ -1454,6 +1469,9 @@ packages:
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
engines: {node: '>=16 || 14 >=14.17'}
+ monaco-editor@0.52.2:
+ resolution: {integrity: sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==}
+
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
@@ -2035,6 +2053,9 @@ packages:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
+ state-local@1.0.7:
+ resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==}
+
string-convert@0.2.1:
resolution: {integrity: sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==}
@@ -2593,6 +2614,18 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.0
+ '@monaco-editor/loader@1.4.0(monaco-editor@0.52.2)':
+ dependencies:
+ monaco-editor: 0.52.2
+ state-local: 1.0.7
+
+ '@monaco-editor/react@4.6.0(monaco-editor@0.52.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@monaco-editor/loader': 1.4.0(monaco-editor@0.52.2)
+ monaco-editor: 0.52.2
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+
'@nodelib/fs.scandir@2.1.5':
dependencies:
'@nodelib/fs.stat': 2.0.5
@@ -3850,6 +3883,8 @@ snapshots:
minipass@7.1.2: {}
+ monaco-editor@0.52.2: {}
+
ms@2.1.3: {}
mz@2.7.0:
@@ -4538,6 +4573,8 @@ snapshots:
source-map-js@1.2.1: {}
+ state-local@1.0.7: {}
+
string-convert@0.2.1: {}
string-width@4.2.3:
diff --git a/src/config/routes.js b/src/config/routes.js
index 1df0c35..25332c4 100644
--- a/src/config/routes.js
+++ b/src/config/routes.js
@@ -18,9 +18,9 @@ const resourceRoutes = [
},
{
path: 'bucket',
- component: lazy(() => import('@/pages/resource/team')),
+ component: lazy(() => import('@/pages/resource/bucket')),
name: '对象存储',
- icon: 'team',
+ icon: 'shop',
},
];
diff --git a/src/pages/resource/bucket/index.jsx b/src/pages/resource/bucket/index.jsx
new file mode 100644
index 0000000..34e7310
--- /dev/null
+++ b/src/pages/resource/bucket/index.jsx
@@ -0,0 +1,528 @@
+import React, { useState, useEffect, useMemo } from 'react';
+import { supabase } from '@/config/supabase';
+import { Card, Upload, Button, message, List, Switch, Space, Input, Select, Tag, Pagination, Modal, Image } from 'antd';
+import { UploadOutlined, FileTextOutlined, FileImageOutlined,
+ FileMarkdownOutlined, FilePdfOutlined, FileWordOutlined,
+ FileExcelOutlined, InboxOutlined, SearchOutlined, EditOutlined } from '@ant-design/icons';
+import MonacoEditor from '@monaco-editor/react';
+
+const { Dragger } = Upload;
+const { Search } = Input;
+
+// 文件类型配置
+const FILE_TYPES = {
+ '图片': ['image/jpeg', 'image/png', 'image/gif', 'image/svg+xml'],
+ '文档': ['application/pdf', 'application/msword',
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+ 'text/plain', 'text/markdown'],
+ '表格': ['application/vnd.ms-excel',
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ 'text/csv'],
+ '代码': ['text/html', 'text/javascript', 'text/css', 'application/json',
+ 'text/jsx', 'text/tsx'],
+ '其他': []
+};
+
+const StorageManager = () => {
+ const [allFiles, setAllFiles] = useState([]);
+ const [loading, setLoading] = useState(false);
+ const [selectedFile, setSelectedFile] = useState(null);
+ const [fileContent, setFileContent] = useState('');
+ const [isPreview, setIsPreview] = useState(false);
+ const [searchText, setSearchText] = useState('');
+ const [selectedType, setSelectedType] = useState('全部');
+ const [pagination, setPagination] = useState({
+ current: 1,
+ pageSize: 200,
+ });
+ const [isRenaming, setIsRenaming] = useState(false);
+ const [newFileName, setNewFileName] = useState('');
+
+ // 文件图标映射
+ const getFileIcon = (file) => {
+ const mimetype = file.metadata?.mimetype;
+ const iconMap = {
+ 'text/plain':
+
点击��拖拽文件到此区域上传
++ 支持单个或批量上传,文件大小不超过50MB +
+