mirror of
https://github.com/Megghy/vtsuru.live.git
synced 2025-12-06 18:36:55 +08:00
update
This commit is contained in:
@@ -3,9 +3,32 @@ import { useAccount } from '@/api/account'
|
||||
import { SongFrom, SongLanguage, SongsInfo } from '@/api/api-models'
|
||||
import { QueryGetAPI, QueryPostAPI } from '@/api/query'
|
||||
import SongList from '@/components/SongList.vue'
|
||||
import { SONG_API_URL } from '@/data/constants'
|
||||
import { FETCH_API, FIVESING_SEARCH_API, SONG_API_URL } from '@/data/constants'
|
||||
import { ca } from 'date-fns/locale'
|
||||
import { FormInst, FormRules, NButton, NDivider, NForm, NFormItem, NInput, NInputGroup, NInputGroupLabel, NModal, NSelect, NSpace, NSpin, NTabPane, NTabs, NTag, NTransfer, useMessage } from 'naive-ui'
|
||||
import {
|
||||
FormInst,
|
||||
FormRules,
|
||||
NButton,
|
||||
NDivider,
|
||||
NForm,
|
||||
NFormItem,
|
||||
NInput,
|
||||
NInputGroup,
|
||||
NInputGroupLabel,
|
||||
NList,
|
||||
NListItem,
|
||||
NModal,
|
||||
NPagination,
|
||||
NSelect,
|
||||
NSpace,
|
||||
NSpin,
|
||||
NTabPane,
|
||||
NTable,
|
||||
NTabs,
|
||||
NTag,
|
||||
NTransfer,
|
||||
useMessage,
|
||||
} from 'naive-ui'
|
||||
import { Option } from 'naive-ui/es/transfer/src/interface'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
|
||||
@@ -14,6 +37,7 @@ const accountInfo = useAccount()
|
||||
|
||||
const showModal = ref(false)
|
||||
const neteaseIdInput = ref()
|
||||
const fivesingSearchInput = ref()
|
||||
const isModalLoading = ref(false)
|
||||
|
||||
const neteaseSongListId = computed(() => {
|
||||
@@ -43,6 +67,12 @@ const neteaseSongs = ref<SongsInfo[]>([])
|
||||
const neteaseSongsOptions = ref<Option[]>([])
|
||||
const selectedNeteaseSongs = ref<string[]>([])
|
||||
|
||||
const fivesingResults = ref<SongsInfo[]>([])
|
||||
const fivesingTotalPageCount = ref(1)
|
||||
const fivesingCurrentPage = ref(1)
|
||||
|
||||
const isGettingFivesingSongPlayUrl = ref(0)
|
||||
|
||||
const formRef = ref<FormInst | null>(null)
|
||||
const addSongModel = ref<SongsInfo>({} as SongsInfo)
|
||||
const addSongRules: FormRules = {
|
||||
@@ -139,6 +169,25 @@ async function addNeteaseSongs() {
|
||||
isModalLoading.value = false
|
||||
})
|
||||
}
|
||||
async function addFingsingSongs(song: SongsInfo) {
|
||||
isModalLoading.value = true
|
||||
await addSongs([song], SongFrom.FiveSing)
|
||||
.then((data) => {
|
||||
if (data.code == 200) {
|
||||
message.success(`已添加歌曲`)
|
||||
songs.value.push(...data.data)
|
||||
} else {
|
||||
message.error('添加失败: ' + data.message)
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
message.error('添加失败')
|
||||
console.error(err)
|
||||
})
|
||||
.finally(() => {
|
||||
isModalLoading.value = false
|
||||
})
|
||||
}
|
||||
async function addSongs(songsShoudAdd: SongsInfo[], from: SongFrom) {
|
||||
return QueryPostAPI<SongsInfo[]>(
|
||||
SONG_API_URL + 'add',
|
||||
@@ -167,19 +216,88 @@ async function getNeteaseSongList() {
|
||||
disabled: songs.value.findIndex((exist) => exist.id == s.id) > -1,
|
||||
}))
|
||||
message.success(`成功获取歌曲信息, 共 ${data.data.length} 条, 歌单中已存在 ${neteaseSongsOptions.value.filter((s) => s.disabled).length} 首`)
|
||||
} else {
|
||||
message.error('获取歌单失败: ' + data.message)
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
message.error(err)
|
||||
message.error('获取歌单失败: ' + err)
|
||||
})
|
||||
.finally(() => {
|
||||
isModalLoading.value = false
|
||||
})
|
||||
}
|
||||
async function getFivesingSearchList(isRestart = false) {
|
||||
isModalLoading.value = true
|
||||
await fetch(FETCH_API + `http://search.5sing.kugou.com/home/json?keyword=${fivesingSearchInput.value}&sort=1&page=${fivesingCurrentPage.value}&filter=3`)
|
||||
.then(async (data) => {
|
||||
const json = await data.json()
|
||||
if (json.list.length == 0) {
|
||||
message.error('搜索结果为空')
|
||||
}
|
||||
if (isRestart) {
|
||||
fivesingCurrentPage.value = 1
|
||||
}
|
||||
fivesingResults.value = []
|
||||
//fivesingResultsOptions.value = []
|
||||
json.list.forEach((song: any) => {
|
||||
const songInfo = {
|
||||
id: song.songId,
|
||||
name: extractTextFromHtml(song.songName),
|
||||
author: [song.originSinger, song.singer],
|
||||
//url: `http://service.5sing.kugou.com/song/getsongurl?songid=${song.songId}&songtype=bz&from=web&version=6.6.72`,
|
||||
} as SongsInfo
|
||||
fivesingResults.value.push(songInfo)
|
||||
})
|
||||
fivesingTotalPageCount.value = json.pageInfo.totalPages
|
||||
message.success(`成功获取搜索信息, 共 ${json.pageInfo.totalCount} 条, 当前第 ${fivesingCurrentPage.value} 页`)
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
message.error('获取歌单失败: ' + err)
|
||||
})
|
||||
.finally(() => {
|
||||
isModalLoading.value = false
|
||||
})
|
||||
}
|
||||
function extractTextFromHtml(html: string): string {
|
||||
const regex = /<em class="keyword">(.*?)<\/em>/
|
||||
const match = regex.exec(html)
|
||||
if (match) {
|
||||
return match[1]
|
||||
} else {
|
||||
return html
|
||||
}
|
||||
}
|
||||
async function playFivesingSong(song: SongsInfo) {
|
||||
isGettingFivesingSongPlayUrl.value = song.id
|
||||
await getFivesingSongUrl(song)
|
||||
.then((data) => {
|
||||
song.url = data
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
message.error('获取歌曲链接失败: ' + err)
|
||||
})
|
||||
.finally(() => {
|
||||
isGettingFivesingSongPlayUrl.value = 0
|
||||
})
|
||||
}
|
||||
async function getFivesingSongUrl(song: SongsInfo): Promise<string> {
|
||||
const data = await fetch(FETCH_API + `http://service.5sing.kugou.com/song/getsongurl?songid=${song.id}&songtype=bz&from=web&version=6.6.72`)
|
||||
const result = await data.text()
|
||||
//忽略掉result的第一个字符和最后一个字符, 并反序列化
|
||||
const json = JSON.parse(result.substring(1, result.length - 1))
|
||||
if (json.code == 0) {
|
||||
return json.data.lqurl
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
async function getSongs() {
|
||||
await QueryGetAPI<any>(SONG_API_URL + 'get', {
|
||||
uId: accountInfo.value?.biliId,
|
||||
id: accountInfo.value?.id,
|
||||
}).then((data) => {
|
||||
if (data.code == 200) {
|
||||
songs.value = data.data
|
||||
@@ -194,7 +312,7 @@ onMounted(async () => {
|
||||
|
||||
<template>
|
||||
<NButton @click="showModal = true"> 添加歌曲 </NButton>
|
||||
<NModal v-model:show="showModal" style="max-width: 600px" preset="card">
|
||||
<NModal v-model:show="showModal" style="max-width: 1000px;" preset="card">
|
||||
<template #header> 添加歌曲 </template>
|
||||
<NSpin :show="isModalLoading">
|
||||
<NTabs default-value="custom" animated>
|
||||
@@ -225,7 +343,7 @@ onMounted(async () => {
|
||||
</template>
|
||||
</NInput>
|
||||
<NDivider style="margin: 10px" />
|
||||
<NButton type="primary" @click="getNeteaseSongList"> 获取 </NButton>
|
||||
<NButton type="primary" @click="getNeteaseSongList" :disabled="!neteaseSongListId"> 获取 </NButton>
|
||||
<template v-if="neteaseSongsOptions.length > 0">
|
||||
<NDivider style="margin: 10px" />
|
||||
<NTransfer style="height: 500px" ref="transfer" v-model:value="selectedNeteaseSongs" :options="neteaseSongsOptions" source-filterable />
|
||||
@@ -233,7 +351,50 @@ onMounted(async () => {
|
||||
<NButton type="primary" @click="addNeteaseSongs"> 添加到歌单 | {{ selectedNeteaseSongs.length }} 首 </NButton>
|
||||
</template>
|
||||
</NTabPane>
|
||||
<NTabPane name="5sing" tab="从5sing搜索"> </NTabPane>
|
||||
<NTabPane name="5sing" tab="从5sing搜索">
|
||||
<NInput clearable style="width: 100%" autosize v-model:value="fivesingSearchInput" placeholder="输入要搜索的歌名" maxlength="15" />
|
||||
<NDivider style="margin: 10px" />
|
||||
<NButton type="primary" @click="getFivesingSearchList(true)" :disabled="!fivesingSearchInput"> 搜索 </NButton>
|
||||
<template v-if="fivesingResults.length > 0">
|
||||
<NDivider style="margin: 10px" />
|
||||
<div style="overflow-x: auto">
|
||||
<NTable size="small" style="overflow-x: auto">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>名称</th>
|
||||
<th>作者</th>
|
||||
<th>试听</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="song in fivesingResults" v-bind:key="song.id">
|
||||
<td>{{ song.name }}</td>
|
||||
<td>
|
||||
<NSpace>
|
||||
<NTag size="small" v-for="author in song.author" :key="author">
|
||||
{{ author }}
|
||||
</NTag>
|
||||
</NSpace>
|
||||
</td>
|
||||
<td style="display: flex; justify-content: flex-end;">
|
||||
<!-- 在这里播放song.url链接中的音频 -->
|
||||
<NButton size="small" v-if="!song.url" @click="playFivesingSong(song)" :loading="isGettingFivesingSongPlayUrl == song.id"> 试听 </NButton>
|
||||
<audio v-else controls autoplay style="max-height: 30px">
|
||||
<source :src="song.url" />
|
||||
</audio>
|
||||
</td>
|
||||
<td>
|
||||
<NButton size="small" color="green" @click="addFingsingSongs(song)" :disabled="songs.findIndex((s) => s.from == SongFrom.FiveSing && s.id == song.id) > -1"> 添加 </NButton>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</NTable>
|
||||
</div>
|
||||
<br />
|
||||
<NPagination v-model:page="fivesingCurrentPage" :page-count="fivesingTotalPageCount" simple @update-page="getFivesingSearchList(false)" />
|
||||
</template>
|
||||
</NTabPane>
|
||||
</NTabs>
|
||||
</NSpin>
|
||||
</NModal>
|
||||
|
||||
Reference in New Issue
Block a user