feat: 新增音乐控制按钮并完善音乐相关逻辑

This commit is contained in:
Zhukj
2025-12-15 10:43:08 +08:00
parent bc8b63d231
commit 0d23216c74
7 changed files with 663 additions and 81 deletions

151
server.js
View File

@@ -13,14 +13,15 @@ const app = express();
const PORT = 3000;
const CONFIG_FILE_PATH = path.join(__dirname, 'data', 'config.json');
// 创建上传目录
// ===================== 原有图片上传配置(保留) =====================
// 创建图片上传目录
const uploadDir = path.join(__dirname, 'uploads');
if (!fs.existsSync(uploadDir)) {
fs.mkdirSync(uploadDir, { recursive: true });
}
// 配置multer
const storage = multer.diskStorage({
// 图片上传multer配置
const imageStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, uploadDir);
},
@@ -32,8 +33,8 @@ const storage = multer.diskStorage({
}
});
const upload = multer({
storage,
const imageUpload = multer({
storage: imageStorage,
limits: { fileSize: 5 * 1024 * 1024 }, // 5MB限制
fileFilter: (req, file, cb) => {
const allowedTypes = /jpeg|jpg|png|gif/;
@@ -47,15 +48,55 @@ const upload = multer({
}
});
// 中间件
// ===================== 新增:音乐上传配置 =====================
// 创建音乐上传目录(对应前端访问路径)
const musicUploadDir = path.join(__dirname, 'public', 'assets', 'music');
// 确保目录存在(不存在则创建)
if (!fs.existsSync(musicUploadDir)) {
fs.mkdirSync(musicUploadDir, { recursive: true });
}
// 音乐上传multer配置
const musicStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, musicUploadDir); // 保存到public/assets/music
},
filename: (req, file, cb) => {
// 保留原文件名+时间戳,避免重复
const timestamp = Date.now();
const ext = path.extname(file.originalname);
const filename = `${timestamp}${ext}`;
cb(null, filename);
}
});
const musicUpload = multer({
storage: musicStorage,
limits: { fileSize: 10 * 1024 * 1024 }, // 10MB音乐文件限制
fileFilter: (req, file, cb) => {
// 仅允许MP3格式
const allowedTypes = /mp3/;
const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase());
const mimetype = allowedTypes.test(file.mimetype) || file.mimetype === 'audio/mpeg';
if (extname && mimetype) {
return cb(null, true);
} else {
cb(new Error('只允许上传MP3格式的音频文件'));
}
}
});
// ===================== 中间件(保留+优化) =====================
app.use(cors());
app.use(express.json());
// 静态文件服务Vue应用上传的图片)
// 静态文件服务Vue应用上传的图片、音乐文件
app.use(express.static(path.join(__dirname, 'dist')));
app.use('/uploads', express.static(uploadDir));
app.use('/assets/music', express.static(musicUploadDir)); // 新增:音乐文件静态访问
// API: 获取配置数据
// ===================== 原有API保留 =====================
// API: 获取整体配置数据
app.get('/api/config', (req, res) => {
try {
const configData = fs.readFileSync(CONFIG_FILE_PATH, 'utf8');
@@ -66,7 +107,7 @@ app.get('/api/config', (req, res) => {
}
});
// API: 保存配置数据
// API: 保存整体配置数据
app.post('/api/config', (req, res) => {
try {
fs.writeFileSync(CONFIG_FILE_PATH, JSON.stringify(req.body, null, 2), 'utf8');
@@ -76,19 +117,92 @@ app.post('/api/config', (req, res) => {
res.status(500).json({ error: '保存配置文件失败' });
}
});
// 第78行新增位置
// API: 获取音乐配置
// ===================== 新增音乐专属API =====================
// API: 获取音乐配置单独返回musicConfig
app.get('/api/musicConfig', (req, res) => {
try {
const configData = fs.readFileSync(CONFIG_FILE_PATH, 'utf8');
const config = JSON.parse(configData);
res.json(config.musicConfig || { enabled: false });
// 兜底如果没有musicConfig返回默认值
res.json(config.musicConfig || {
enabled: false,
filePath: '/assets/music/background.mp3'
});
} catch (error) {
res.status(500).json({ enabled: false });
console.error('读取音乐配置失败:', error);
res.status(500).json({
enabled: false,
filePath: '/assets/music/background.mp3'
});
}
});
// API: 更新音乐配置仅更新musicConfig节点不影响其他配置
app.post('/api/musicConfig', (req, res) => {
try {
// 1. 读取原有配置
const configData = fs.readFileSync(CONFIG_FILE_PATH, 'utf8');
const config = JSON.parse(configData);
// 2. 校验参数
const { enabled, filePath } = req.body;
if (typeof enabled !== 'boolean' || !filePath) {
return res.status(400).json({
success: false,
error: '参数错误enabled必须为布尔值filePath不能为空'
});
}
// 3. 更新musicConfig节点保留其他配置不变
config.musicConfig = { enabled, filePath };
// 4. 写入配置文件
fs.writeFileSync(CONFIG_FILE_PATH, JSON.stringify(config, null, 2), 'utf8');
res.json({
success: true,
data: config.musicConfig
});
} catch (error) {
console.error('更新音乐配置失败:', error);
res.status(500).json({
success: false,
error: '更新音乐配置失败'
});
}
});
// API: 上传音乐文件
app.post('/api/upload/music', musicUpload.single('musicFile'), (req, res) => {
try {
if (!req.file) {
return res.status(400).json({
success: false,
error: '没有选择要上传的音乐文件'
});
}
// 返回前端可访问的音乐路径对应public/assets/music
const relativePath = `/assets/music/${req.file.filename}`;
res.json({
success: true,
filePath: relativePath, // 音乐访问路径
filename: req.file.filename,
originalName: req.file.originalname
});
} catch (error) {
console.error('音乐文件上传失败:', error);
res.status(500).json({
success: false,
error: error.message || '音乐文件上传失败'
});
}
});
// ===================== 原有图片上传/删除API保留 =====================
// API: 上传图片
app.post('/api/upload', upload.single('image'), (req, res) => {
app.post('/api/upload', imageUpload.single('image'), (req, res) => {
try {
if (!req.file) {
return res.status(400).json({ error: '没有文件上传' });
@@ -125,16 +239,23 @@ app.delete('/api/upload/:filename', (req, res) => {
}
});
// ===================== 前端路由兼容(保留) =====================
// 处理Vue Router历史模式 - 使用正则表达式代替通配符
app.get(/^((?!\/api).)*$/, (req, res) => {
res.sendFile(path.join(__dirname, 'dist', 'index.html'));
});
// ===================== 服务器启动(保留+优化) =====================
// 启动服务器并监听错误
const server = app.listen(PORT, '0.0.0.0', () => {
console.log(`服务器运行在 http://localhost:${PORT}`);
console.log('服务器已成功启动,可以访问 http://localhost:3000');
console.log('API端点: GET/POST /api/config');
console.log('API端点:');
console.log(' - 整体配置: GET/POST /api/config');
console.log(' - 音乐配置: GET/POST /api/musicConfig');
console.log(' - 图片上传: POST /api/upload');
console.log(' - 音乐上传: POST /api/upload/music');
console.log(' - 图片删除: DELETE /api/upload/:filename');
});
// 监听服务器错误