1. 播放器

This commit is contained in:
李琦
2026-08-01 17:59:07 +08:00
parent 366e3b329f
commit d824b9945e
9 changed files with 621 additions and 67 deletions

View File

@@ -188,6 +188,27 @@
</a-button>
<a-button size="small" danger @click="removeMusic(i)"><i class="fa-solid fa-trash"></i></a-button>
</div>
<div class="flex flex-wrap gap-4 mt-3 items-start">
<div>
<div class="text-[11px] text-[#8A8680] mb-1">封面</div>
<image-field
v-model="t.coverUrl"
label="封面"
@pick="openUpload(u => t.coverUrl = u)"
:uploading="uploading"
/>
</div>
<div class="flex-1 min-w-[180px]">
<div class="text-[11px] text-[#8A8680] mb-1">歌词 LRC</div>
<div class="flex items-center gap-2 flex-wrap">
<a-button size="small" @click="openLrcUpload(t)">
<i class="fa-solid fa-file-lines mr-1"></i>{{ t.lrcUrl ? '更换歌词' : '上传歌词' }}
</a-button>
<a-button v-if="t.lrcUrl" size="small" danger type="link" @click="t.lrcUrl = ''">清除</a-button>
</div>
<div v-if="t.lrcUrl" class="text-[10px] text-[#8A8680] mt-1 truncate max-w-[280px]">{{ shortUrl(t.lrcUrl) }}</div>
</div>
</div>
<audio v-if="t.url" :src="t.url" controls class="w-full mt-3" style="height: 36px;"></audio>
</a-card>
<a-button class="mt-1" @click="openMusicUpload">
@@ -658,7 +679,7 @@ function openMusicUpload() {
const name = file.name.replace(/\.[^.]+$/, '') || '背景音乐'
const url = res.url
if (!cfg.musicList) cfg.musicList = []
cfg.musicList.push({ url, name })
cfg.musicList.push({ url, name, coverUrl: '', lrcUrl: '' })
if (!cfg.activeMusicUrl) cfg.activeMusicUrl = url
message.success('音乐上传成功')
} catch (err) {
@@ -669,6 +690,29 @@ function openMusicUpload() {
}
input.click()
}
function openLrcUpload(track) {
const input = document.createElement('input')
input.type = 'file'
input.accept = '.lrc,text/plain'
input.onchange = async (e) => {
const file = e.target.files[0]
if (!file) return
uploading.value = true
try {
const res = await uploadImage(file)
track.lrcUrl = res.url
message.success('歌词上传成功')
} catch {
message.error('歌词上传失败')
} finally {
uploading.value = false
e.target.value = ''
}
}
input.click()
}
function setActiveMusic(url) { cfg.activeMusicUrl = url }
function removeMusic(i) {
cfg.musicList.splice(i, 1)
@@ -801,9 +845,16 @@ onMounted(async () => {
const loaded = typeof res.data === 'string' ? JSON.parse(res.data) : res.data
// 兼容旧版单链接 musicUrl
if (loaded.musicUrl && !(loaded.musicList && loaded.musicList.length)) {
loaded.musicList = [{ url: loaded.musicUrl, name: '背景音乐' }]
loaded.musicList = [{ url: loaded.musicUrl, name: '背景音乐', coverUrl: '', lrcUrl: '' }]
loaded.activeMusicUrl = loaded.musicUrl
}
if (Array.isArray(loaded.musicList)) {
loaded.musicList = loaded.musicList.map((t) => ({
...t,
coverUrl: t.coverUrl || '',
lrcUrl: t.lrcUrl || '',
}))
}
loaded.endImg = loaded.endImg || loaded.heroImg || cfg.endImg
Object.assign(cfg, loaded)
cfg.formalPageHeight = cfg.formalPageHeight || '100vh'