feat:新增背景音乐设置,音乐切换功能

This commit is contained in:
Zhukj
2025-12-15 15:45:50 +08:00
parent 0d23216c74
commit 9ba67e55cd
5 changed files with 188 additions and 69 deletions

View File

@@ -92,6 +92,24 @@
</span>
</div>
<!-- 新增已上传音乐列表 -->
<div class="music-list-section" style="margin: 20px 0;">
<h4 class="text-gold">🎵 已上传音乐列表</h4>
<div class="music-list" v-if="musicList.length > 0">
<div
class="music-item"
v-for="music in musicList"
:key="music.filePath"
:class="{ active: music.filePath === currentMusicPath }"
@click="switchToMusic(music.filePath)"
>
{{ music.filename }}
<span v-if="music.filePath === currentMusicPath" style="color: #667eea; margin-left: 8px;"> 当前使用</span>
</div>
</div>
<p v-else class="upload-hint">暂无已上传的音乐文件</p>
</div>
<!-- 当前音乐路径回显对齐Logo大小配置 -->
<div class="config-item" style="margin: 10px 0;">
<label class="checkbox-label">
@@ -858,6 +876,7 @@ const selectedMusicFile = ref(null); // 选中的MP3文件
const uploadMsg = ref(''); // 上传提示信息
const musicEnabled = ref(false); // 首页播放开关状态
const currentMusicPath = ref(''); // 当前音乐路径
const musicList = ref([]); // 新增:已上传音乐列表
// 返回首页
const goToHome = () => {
router.push('/');
@@ -916,7 +935,42 @@ const handleMusicFileChange = (e) => {
}
};
// 2. 上传并切换音乐文件更新config.json+实时生效
// 新增:获取已上传音乐列表(调用后端/api/music/list接口
const fetchMusicList = async () => {
try {
const res = await fetch('http://localhost:3000/api/music/list');
const data = await res.json();
if (data.success) {
musicList.value = data.data;
} else {
uploadMsg.value = `⚠️ 获取音乐列表失败:${data.error}`;
}
} catch (err) {
uploadMsg.value = `⚠️ 获取音乐列表异常:${err.message}`;
}
};
// 新增:点击列表项切换音乐
const switchToMusic = async (filePath) => {
try {
uploadMsg.value = '⏳ 正在切换音乐...';
// 调用后端接口更新config.json的音乐路径
await updateMusicConfig(musicEnabled.value, filePath);
// 回显新路径到页面
currentMusicPath.value = filePath;
// 实时切换播放器音乐(和原有上传逻辑保持一致)
musicPlayer.updateMusicPath(filePath);
// 若开关开启,立即播放新音乐
if (musicEnabled.value) {
musicPlayer.play();
}
uploadMsg.value = '✅ 音乐切换成功!';
} catch (err) {
uploadMsg.value = `❌ 切换音乐失败:${err.message}`;
}
};
// 修改原handleMusicUpload方法在上传成功后添加fetchMusicList()
const handleMusicUpload = async () => {
if (!selectedMusicFile.value) {
uploadMsg.value = '❌ 请先选择MP3文件';
@@ -925,30 +979,25 @@ const handleMusicUpload = async () => {
uploadMsg.value = '⏳ 正在上传音乐文件...';
try {
// 构建FormData适配后端上传接口
const formData = new FormData();
formData.append('music', selectedMusicFile.value);
// 调用上传接口(替换为你的实际接口地址)
const response = await fetch('/api/upload-music', {
formData.append('musicFile', selectedMusicFile.value);
const response = await fetch('http://localhost:3000/upload-music', {
method: 'POST',
body: formData
});
const uploadResult = await response.json();
if (uploadResult.success) {
// 更新config.json的filePath保留开关状态
await updateMusicConfig(musicEnabled.value, uploadResult.filePath);
// 回显新路径
currentMusicPath.value = uploadResult.filePath;
// 实时切换播放器音乐
musicPlayer.updateMusicPath(uploadResult.filePath);
// 若开关开启,立即播放
if (musicEnabled.value) {
musicPlayer.play();
}
// 新增:上传成功后刷新列表
await fetchMusicList();
uploadMsg.value = '✅ 音乐上传成功!已自动应用到首页';
selectedMusicFile.value = null; // 清空选中文件
selectedMusicFile.value = null;
} else {
uploadMsg.value = `❌ 上传失败:${uploadResult.error}`;
}
@@ -987,6 +1036,7 @@ const initMusicConfig = async () => {
const config = await getMusicConfig();
musicEnabled.value = config.enabled ?? false; // 兼容默认值
currentMusicPath.value = config.filePath || '/assets/music/background.mp3'; // 默认路径
await fetchMusicList();// 新增:初始化时加载已上传列表
} catch (err) {
uploadMsg.value = `⚠️ 音乐配置初始化失败:${err.message}`;
// 初始化默认值
@@ -2193,4 +2243,36 @@ const deleteBonusRule = (index) => {
border-bottom: 2px solid #eee;
padding-bottom: 10px;
}
/* 新增:已上传音乐列表样式 */
.music-list-section {
margin: 20px 0;
padding: 15px;
background: #f8f9fa;
border-radius: 8px;
}
.music-list {
display: flex;
flex-direction: column;
gap: 8px;
margin-top: 10px;
}
.music-item {
padding: 10px 15px;
background: white;
border-radius: 4px;
border: 1px solid #eee;
cursor: pointer;
transition: all 0.2s;
}
.music-item:hover {
background: #f0f7ff;
border-color: #667eea;
}
.music-item.active {
background: #e6f0ff;
border-color: #667eea;
font-weight: 500;
}
</style>