feat: 更新VIP权限选项为2,优化音乐下载功能,支持通过fetch API下载文件并处理二进制数据,增强用户体验。
This commit is contained in:
@@ -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
|
||||||
|
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 = (musicName || 'music') + fileExtension;
|
||||||
|
|
||||||
// 创建下载链接
|
// 创建下载链接
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
link.href = downloadUrl;
|
link.href = url;
|
||||||
link.download = musicName || 'music';
|
link.download = downloadFileName;
|
||||||
link.target = '_blank';
|
|
||||||
document.body.appendChild(link);
|
document.body.appendChild(link);
|
||||||
link.click();
|
link.click();
|
||||||
document.body.removeChild(link);
|
document.body.removeChild(link);
|
||||||
|
|
||||||
this.$modal.msgSuccess(`正在下载音乐: ${musicName || '未知文件'}`);
|
// 释放URL对象
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
|
||||||
|
this.$modal.msgSuccess(`音乐文件下载完成: ${downloadFileName}`);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('下载失败:', error);
|
||||||
|
this.$modal.msgError("下载失败,请重试");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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("下载失败,请重试");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user