feat: 更新VIP权限选项为2,优化音乐下载功能,支持通过fetch API下载文件并处理二进制数据,增强用户体验。

This commit is contained in:
wangjie52
2025-08-02 23:02:39 +08:00
parent c2fb204692
commit 7be046e8f5
3 changed files with 160 additions and 28 deletions

View File

@@ -21,7 +21,7 @@
</el-form-item> </el-form-item>
<el-form-item label="VIP权限" prop="vip"> <el-form-item label="VIP权限" prop="vip">
<el-select v-model="queryParams.vip" placeholder="选择VIP权限" clearable style="width: 150px"> <el-select v-model="queryParams.vip" placeholder="选择VIP权限" clearable style="width: 150px">
<el-option label="免费" :value="0" /> <el-option label="免费" :value="2" />
<el-option label="VIP" :value="1" /> <el-option label="VIP" :value="1" />
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -70,7 +70,7 @@
v-if="scope.row.musicAddr" v-if="scope.row.musicAddr"
type="primary" type="primary"
:underline="false" :underline="false"
@click="downloadMusic(scope.row.musicAddr, scope.row.name)" @click="downloadMusic(scope.row.musicAddr, scope.row.name, scope.row.musicId)"
> >
<i class="el-icon-download"></i> 下载 <i class="el-icon-download"></i> 下载
</el-link> </el-link>
@@ -151,7 +151,7 @@
</el-form-item> </el-form-item>
<el-form-item label="VIP权限" prop="vip" required> <el-form-item label="VIP权限" prop="vip" required>
<el-select v-model="form.vip" placeholder="请选择VIP权限" style="width: 100%"> <el-select v-model="form.vip" placeholder="请选择VIP权限" style="width: 100%">
<el-option label="免费" :value="0" /> <el-option label="免费" :value="2" />
<el-option label="VIP" :value="1" /> <el-option label="VIP" :value="1" />
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -196,7 +196,7 @@
<el-link <el-link
type="primary" type="primary"
:underline="false" :underline="false"
@click="downloadMusic(form.musicAddr, form.name)" @click="downloadMusic(form.musicAddr, form.name, form.musicId)"
> >
<i class="el-icon-download"></i> 下载当前音乐文件 <i class="el-icon-download"></i> 下载当前音乐文件
</el-link> </el-link>
@@ -221,6 +221,7 @@
import { listNormalSong, getNormalSong, delNormalSong, addNormalSong, updateNormalSong } from "@/api/playlist/normal"; import { listNormalSong, getNormalSong, delNormalSong, addNormalSong, updateNormalSong } from "@/api/playlist/normal";
import { listTags } from "@/api/playlist/tag"; import { listTags } from "@/api/playlist/tag";
import { getImageUrl } from "@/utils/image"; import { getImageUrl } from "@/utils/image";
import request from '@/utils/request';
export default { export default {
name: "Normal", name: "Normal",
@@ -309,7 +310,7 @@ export default {
musicId: null, musicId: null,
name: null, name: null,
author: null, author: null,
vip: 0, vip: 2,
shelf: 1, shelf: 1,
imgAddr: null, imgAddr: null,
musicAddr: null, musicAddr: null,
@@ -405,28 +406,79 @@ export default {
}).catch(() => {}); }).catch(() => {});
}, },
// 下载音乐文件 // 下载音乐文件
downloadMusic(musicAddr, musicName) { downloadMusic(musicAddr, musicName, musicId) {
if (!musicAddr) { if (!musicAddr) {
this.$modal.msgError("音乐文件地址为空,无法下载"); this.$modal.msgError("音乐文件地址为空,无法下载");
return; return;
} }
// 构建完整的下载URL // 构建下载URL直接使用相对路径让request自动处理baseUrl
let downloadUrl = musicAddr; let downloadUrl = musicAddr;
if (!musicAddr.startsWith('http://') && !musicAddr.startsWith('https://')) {
downloadUrl = process.env.VUE_APP_BASE_API + musicAddr; // 拼接musicId参数
if (!downloadUrl.includes('?')) {
downloadUrl += '?musicId=' + musicId;
} else {
downloadUrl += '&musicId=' + musicId;
} }
// 创建下载链接 // 构建完整的URL
const link = document.createElement('a'); if (!musicAddr.startsWith('http://') && !musicAddr.startsWith('https://')) {
link.href = downloadUrl; downloadUrl = process.env.VUE_APP_BASE_API + downloadUrl;
link.download = musicName || 'music'; }
link.target = '_blank';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
this.$modal.msgSuccess(`正在下载音乐: ${musicName || '未知文件'}`); // 使用fetch API下载文件确保正确处理二进制数据
this.$message.info("正在下载音乐文件...");
fetch(downloadUrl, {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + this.$store.getters.token
}
})
.then(response => {
if (!response.ok) {
throw new Error('下载失败');
}
return response.blob();
})
.then(blob => {
// 从URL中提取文件扩展名
let fileExtension = '';
if (musicAddr) {
const urlParts = musicAddr.split('.');
if (urlParts.length > 1) {
fileExtension = '.' + urlParts[urlParts.length - 1].split('?')[0]; // 移除查询参数
}
}
// 如果没有扩展名,默认使用.mp3
if (!fileExtension || fileExtension === '.') {
fileExtension = '.mp3';
}
// 构建下载文件名
const downloadFileName = (musicName || 'music') + fileExtension;
// 创建下载链接
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = downloadFileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
// 释放URL对象
window.URL.revokeObjectURL(url);
this.$modal.msgSuccess(`音乐文件下载完成: ${downloadFileName}`);
})
.catch(error => {
console.error('下载失败:', error);
this.$modal.msgError("下载失败,请重试");
});
} }
} }
}; };

View File

@@ -127,7 +127,7 @@
</el-form-item> </el-form-item>
<el-form-item label="VIP权限" prop="vip" required> <el-form-item label="VIP权限" prop="vip" required>
<el-select v-model="form.vip" placeholder="请选择VIP权限" style="width: 100%"> <el-select v-model="form.vip" placeholder="请选择VIP权限" style="width: 100%">
<el-option label="免费" :value="0" /> <el-option label="免费" :value="2" />
<el-option label="VIP" :value="1" /> <el-option label="VIP" :value="1" />
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -324,7 +324,7 @@ export default {
{ label: '上架', value: 1 } { label: '上架', value: 1 }
], ],
permissionOptions: [ permissionOptions: [
{ label: '免费', value: 0 }, { label: '免费', value: 2 },
{ label: 'VIP', value: 1 } { label: 'VIP', value: 1 }
], ],
selectedMusicInfo: null, // 用于存储选中的音乐信息 selectedMusicInfo: null, // 用于存储选中的音乐信息
@@ -453,25 +453,22 @@ export default {
this.open = false; this.open = false;
this.reset(); this.reset();
}, },
// 表单重置
reset() { reset() {
this.form = { this.form = {
id: null, id: null,
musicId: null, musicId: null,
name: null, name: null,
author: null, author: null,
vip: 0, vip: 2,
shelf: 1, shelf: 1,
imgAddr: null, imgAddr: null,
musicType: "mixing", musicType: "mixing",
label: null, label: null,
musicScenes: null, musicScenes: null
musicScene: {
sceneIds: ""
}
}; };
this.selectedTags = []; this.selectedTags = [];
this.selectedScenes = []; this.selectedMusicInfo = null;
this.selectedMusicInfo = null; // 清空选中的音乐信息
this.resetForm("form"); this.resetForm("form");
}, },
handleQuery() { handleQuery() {

View File

@@ -37,7 +37,14 @@
</el-table-column> </el-table-column>
<el-table-column label="音乐地址" align="center" prop="musicAddr" :show-overflow-tooltip="true"> <el-table-column label="音乐地址" align="center" prop="musicAddr" :show-overflow-tooltip="true">
<template slot-scope="scope"> <template slot-scope="scope">
<span v-if="scope.row.musicAddr">{{ scope.row.musicAddr }}</span> <el-link
v-if="scope.row.musicAddr"
type="primary"
:underline="false"
@click="downloadMusic(scope.row.musicAddr, scope.row.scene, scope.row.sceneId)"
>
<i class="el-icon-download"></i> 下载
</el-link>
<span v-else>-</span> <span v-else>-</span>
</template> </template>
</el-table-column> </el-table-column>
@@ -103,6 +110,7 @@
<script> <script>
import { listScene, getScene, delScene, addScene, updateScene } from "@/api/playlist/scene"; import { listScene, getScene, delScene, addScene, updateScene } from "@/api/playlist/scene";
import { getImageUrl } from "@/utils/image"; import { getImageUrl } from "@/utils/image";
import request from '@/utils/request';
export default { export default {
name: "Scene", name: "Scene",
@@ -235,6 +243,81 @@ export default {
this.getList(); this.getList();
this.$modal.msgSuccess("删除成功"); this.$modal.msgSuccess("删除成功");
}).catch(() => {}); }).catch(() => {});
},
// 下载音乐文件
downloadMusic(musicAddr, sceneName, sceneId) {
if (!musicAddr) {
this.$modal.msgError("音乐文件地址为空,无法下载");
return;
}
// 构建下载URL直接使用相对路径让request自动处理baseUrl
let downloadUrl = musicAddr;
// 拼接sceneId参数
if (!downloadUrl.includes('?')) {
downloadUrl += '?musicId=' + sceneId;
} else {
downloadUrl += '&musicId=' + sceneId;
}
// 构建完整的URL
if (!musicAddr.startsWith('http://') && !musicAddr.startsWith('https://')) {
downloadUrl = process.env.VUE_APP_BASE_API + downloadUrl;
}
// 使用fetch API下载文件确保正确处理二进制数据
this.$message.info("正在下载音乐文件...");
fetch(downloadUrl, {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + this.$store.getters.token
}
})
.then(response => {
if (!response.ok) {
throw new Error('下载失败');
}
return response.blob();
})
.then(blob => {
// 从URL中提取文件扩展名
let fileExtension = '';
if (musicAddr) {
const urlParts = musicAddr.split('.');
if (urlParts.length > 1) {
fileExtension = '.' + urlParts[urlParts.length - 1].split('?')[0]; // 移除查询参数
}
}
// 如果没有扩展名,默认使用.mp3
if (!fileExtension || fileExtension === '.') {
fileExtension = '.mp3';
}
// 构建下载文件名
const downloadFileName = (sceneName || 'scene_music') + fileExtension;
// 创建下载链接
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = downloadFileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
// 释放URL对象
window.URL.revokeObjectURL(url);
this.$modal.msgSuccess(`音乐文件下载完成: ${downloadFileName}`);
})
.catch(error => {
console.error('下载失败:', error);
this.$modal.msgError("下载失败,请重试");
});
} }
} }
}; };