下面我将为您介绍如何实现这个爱心盒子项目的开发,分为前端、后端和数据库三个部分:
一、项目结构
love-box/
├── client/ # 前端
│ ├── css/
│ ├── js/
│ ├── media/ # 本地测试用媒体文件
│ └── index.html
├── server/ # 后端
│ ├── routes/
│ ├── models/
│ ├── config/
│ └── app.js
├── uploads/ # 上传文件存储目录
└── package.json
二、前端实现(HTML/CSS/JavaScript)
<!-- index.html -->
<div class="container">
<div class="heart" onclick="openBox()"></div>
<div class="content hidden">
<div class="media-container" id="mediaList"></div>
<input type="file" id="uploadInput" multiple>
<button onclick="uploadFile()">上传回忆</button>
</div>
<audio id="bgm" src="love-song.mp3"></audio>
</div>
/* CSS */
.heart {
width: 100px;
height: 100px;
background: #ff3366;
position: relative;
transform: rotate(45deg);
cursor: pointer;
transition: all 0.5s;
}
.heart::before,
.heart::after {
content: '';
width: 100px;
height: 100px;
background: #ff3366;
border-radius: 50%;
position: absolute;
}
.heart::before { top: -50px; left: 0 }
.heart::after { left: -50px; top: 0 }
.open {
transform: rotate(135deg) scale(1.5);
opacity: 0;
}
.content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.hidden { display: none; }
// JavaScript
function openBox() {
document.querySelector('.heart').classList.add('open');
document.querySelector('.content').classList.remove('hidden');
document.getElementById('bgm').play();
fetchMedia(); // 获取媒体列表
}
async function fetchMedia() {
const res = await fetch('http://localhost:3000/api/media');
const mediaList = await res.json();
renderMedia(mediaList);
}
function renderMedia(list) {
const container = document.getElementById('mediaList');
container.innerHTML = list.map(item => `
<div class="media-item">
${item.type === 'video' ?
`<video controls src="${item.url}"></video>` :
`<audio controls src="${item.url}"></audio>`}
<p>${item.title}</p>
</div>
`).join('');
}
async function uploadFile() {
const files = document.getElementById('uploadInput').files;
const formData = new FormData();
for (let file of files) {
formData.append('media', file);
}
await fetch('http://localhost:3000/api/upload', {
method: 'POST',
body: formData
});
fetchMedia();
}
三、后端实现(Node.js/Express)
// app.js
const express = require('express');
const multer = require('multer');
const cors = require('cors');
const path = require('path');
const Media = require('./models/Media');
const app = express();
app.use(cors());
app.use(express.json());
// 文件上传配置
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/')
},
filename: (req, file, cb) => {
cb(null, Date.now() + path.extname(file.originalname))
}
});
const upload = multer({ storage });
// 路由
app.get('/api/media', async (req, res) => {
try {
const media = await Media.find();
res.json(media);
} catch (err) {
res.status(500).send(err);
}
});
app.post('/api/upload', upload.array('media'), async (req, res) => {
try {
const files = req.files.map(file => ({
title: file.originalname,
url: `http://localhost:3000/uploads/${file.filename}`,
type: file.mimetype.split('/')[0]
}));
await Media.insertMany(files);
res.status(201).send('上传成功');
} catch (err) {
res.status(500).send(err);
}
});
// 静态文件服务
app.use('/uploads', express.static('uploads'));
app.listen(3000, () => {
console.log('Server running on port 3000');
});
四、数据库模型(Mongoose)
// models/Media.js
const mongoose = require('mongoose');
const mediaSchema = new mongoose.Schema({
title: String,
url: String,
type: String, // 'audio' 或 'video'
createdAt: { type: Date, default: Date.now }
});
module.exports = mongoose.model('Media', mediaSchema);
五、运行步骤
- 安装依赖:
npm install express mongoose multer cors
-
启动MongoDB并创建数据库
-
配置数据库连接:
// config/db.js
mongoose.connect('mongodb://localhost/lovebox', {
useNewUrlParser: true,
useUnifiedTopology: true
});
- 运行项目:
node server/app.js
六、扩展功能建议
- 用户认证系统(JWT)
- 媒体分类标签
- 留言墙功能
- 时间轴展示
- 响应式设计适配移动端
七、部署建议
- 使用Nginx作为反向代理
- 使用云存储服务(如AWS S3)替代本地存储
- 添加HTTPS支持
- 实现文件分片上传
- 添加媒体文件格式验证
这个项目结合了前端动画、媒体播放、文件上传和RESTful API开发等多个技术点。开发过程中建议使用Postman测试API接口,使用Chrome开发者工具调试前端功能。