diff --git a/backend/backgroundSettings.json b/backend/backgroundSettings.json new file mode 100644 index 0000000..ffa3dda --- /dev/null +++ b/backend/backgroundSettings.json @@ -0,0 +1,5 @@ +{ + "type": "image", + "image": "/uploads/1766210792626_生成情侣图片.png", + "size": "cover" +} \ No newline at end of file diff --git a/backend/fileIndex.json b/backend/fileIndex.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/backend/fileIndex.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/backend/routes/background.js b/backend/routes/background.js new file mode 100644 index 0000000..1ec3e40 --- /dev/null +++ b/backend/routes/background.js @@ -0,0 +1,73 @@ +const express = require('express'); +const path = require('path'); +const fs = require('fs'); +const router = express.Router(); + +// 确保上传目录存在 +const UPLOAD_DIR = path.join(__dirname, '../uploads'); +if (!fs.existsSync(UPLOAD_DIR)) { + fs.mkdirSync(UPLOAD_DIR, { recursive: true }); +} + +// 确保背景设置文件存在 +const SETTINGS_FILE = path.join(__dirname, '../backgroundSettings.json'); +if (!fs.existsSync(SETTINGS_FILE)) { + fs.writeFileSync(SETTINGS_FILE, JSON.stringify({ + type: 'gradient', + image: '', + size: 'contain' + }, null, 2)); +} + +// 上传图片接口 +router.post('/upload', (req, res) => { + try { + if (!req.files || !req.files.file) { + return res.status(400).json({ error: '没有上传文件' }); + } + + const file = req.files.file; + const fileName = `${Date.now()}_${file.name}`; + const filePath = path.join(UPLOAD_DIR, fileName); + + // 保存文件到服务器 + file.mv(filePath, (err) => { + if (err) { + console.error('文件保存失败:', err); + return res.status(500).json({ error: '文件保存失败' }); + } + + // 返回文件路径 + const fileUrl = `/uploads/${fileName}`; + res.json({ path: fileUrl }); + }); + } catch (error) { + console.error('上传错误:', error); + res.status(500).json({ error: '上传失败' }); + } +}); + +// 获取背景设置 +router.get('/settings', (req, res) => { + try { + const settings = JSON.parse(fs.readFileSync(SETTINGS_FILE, 'utf8')); + res.json(settings); + } catch (error) { + console.error('读取背景设置失败:', error); + res.status(500).json({ error: '读取背景设置失败' }); + } +}); + +// 保存背景设置 +router.post('/settings', (req, res) => { + try { + const settings = req.body; + fs.writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2)); + res.json({ success: true }); + } catch (error) { + console.error('保存背景设置失败:', error); + res.status(500).json({ error: '保存背景设置失败' }); + } +}); + +module.exports = router; \ No newline at end of file diff --git a/backend/server.js b/backend/server.js index 139fe01..c1498f8 100644 --- a/backend/server.js +++ b/backend/server.js @@ -38,12 +38,17 @@ const deviceRoutes = require('./routes/devices'); const rackRoutes = require('./routes/racks'); const roomRoutes = require('./routes/rooms'); const deviceFieldRoutes = require('./routes/deviceFields'); +const backgroundRoutes = require('./routes/background'); // 使用路由 app.use('/api/devices', deviceRoutes); app.use('/api/racks', rackRoutes); app.use('/api/rooms', roomRoutes); app.use('/api/deviceFields', deviceFieldRoutes); +app.use('/api/background', backgroundRoutes); + +// 静态文件服务 +app.use('/uploads', express.static('uploads')); // 健康检查 app.get('/health', (req, res) => { diff --git a/frontend/src/pages/RackVisualization.jsx b/frontend/src/pages/RackVisualization.jsx index 369d77b..3eef36f 100644 --- a/frontend/src/pages/RackVisualization.jsx +++ b/frontend/src/pages/RackVisualization.jsx @@ -145,6 +145,7 @@ function RackVisualization() { const [backgroundImage, setBackgroundImage] = useState(null); const [backgroundType, setBackgroundType] = useState('gradient'); // gradient or image const [backgroundSize, setBackgroundSize] = useState('contain'); // cover, contain, auto + const [uploading, setUploading] = useState(false); // 上传状态 // 获取所有机柜 const fetchRacks = async () => { @@ -333,6 +334,7 @@ function RackVisualization() { useEffect(() => { fetchRacks(); + loadBackgroundSettings(); }, []); // 根据设备类型获取图标 @@ -617,6 +619,33 @@ function RackVisualization() { message.success('数据已刷新'); }); }; + + // 保存背景设置到服务器 + const saveBackgroundSettings = async (type, image, size) => { + try { + await axios.post('/api/background/settings', { + type, + image, + size + }); + } catch (error) { + console.error('保存背景设置失败:', error); + } + }; + + // 从服务器加载背景设置 + const loadBackgroundSettings = async () => { + try { + const response = await axios.get('/api/background/settings'); + if (response.data) { + setBackgroundType(response.data.type || 'gradient'); + setBackgroundImage(response.data.image || null); + setBackgroundSize(response.data.size || 'contain'); + } + } catch (error) { + console.error('加载背景设置失败:', error); + } + }; // 重置视角 const handleResetView = () => { @@ -689,45 +718,78 @@ function RackVisualization() { - {backgroundType === 'image' && ( - - setBackgroundImage(e.target.value)} - value={backgroundImage || ''} - /> + placeholder="选择背景类型" + style={{ width: 150 }} + value={backgroundType} + onChange={async (type) => { + setBackgroundType(type); + await saveBackgroundSettings(type, backgroundImage, backgroundSize); + }} + > + + + + {backgroundType === 'image' && ( + + { + const image = e.target.value; + setBackgroundImage(image); + await saveBackgroundSettings(backgroundType, image, backgroundSize); + }} + value={backgroundImage || ''} + /> { + onChange={async (e) => { const file = e.target.files[0]; if (file) { - const reader = new FileReader(); - reader.onload = (event) => { - setBackgroundImage(event.target.result); - }; - reader.readAsDataURL(file); + try { + setUploading(true); + const formData = new FormData(); + formData.append('file', file); + formData.append('type', 'background'); + + // 发送图片到服务器 + const response = await axios.post('/api/background/upload', formData, { + headers: { + 'Content-Type': 'multipart/form-data' + } + }); + + // 保存服务器返回的图片路径 + if (response.data && response.data.path) { + setBackgroundImage(response.data.path); + message.success('背景图片上传成功'); + // 保存背景设置到服务器 + await saveBackgroundSettings('image', response.data.path, backgroundSize); + } else { + message.error('上传失败:服务器返回格式不正确'); + } + } catch (error) { + console.error('上传失败:', error); + message.error('背景图片上传失败,请重试'); + } finally { + setUploading(false); + } } }} style={{ display: 'none' }} id="backgroundFileInput" /> - +