allow custom song language

This commit is contained in:
2024-04-19 00:56:33 +08:00
parent 000963fd38
commit df1e75caa5
4 changed files with 62 additions and 38 deletions

View File

@@ -276,7 +276,7 @@ export interface SongsInfo {
author: string[] author: string[]
url: string url: string
from: SongFrom from: SongFrom
language: SongLanguage[] language: string[]
description?: string description?: string
tags?: string[] tags?: string[]
createTime: number createTime: number

View File

@@ -80,7 +80,7 @@ const debouncedInput = refDebounced(searchMusicKeyword, 500)
const batchUpdate_Author = ref<string[]>([]) const batchUpdate_Author = ref<string[]>([])
const batchUpdate_Tag = ref<string[]>([]) const batchUpdate_Tag = ref<string[]>([])
const batchUpdate_Language = ref<SongLanguage[]>([]) const batchUpdate_Language = ref<string[]>([])
const batchUpdate_Option = ref<SongRequestOption>() const batchUpdate_Option = ref<SongRequestOption>()
const playingSong = ref<SongsInfo>() const playingSong = ref<SongsInfo>()
@@ -127,6 +127,18 @@ const songSelectOption = [
value: SongLanguage.Other, value: SongLanguage.Other,
}, },
] ]
const languageSelectOption = computed(() => {
const languages = new Set<string>(songSelectOption.map((s) => s.label))
songsInternal.value.forEach((s) => {
if (s.language) {
s.language.forEach((l) => languages.add(l))
}
})
return [...languages].map((t) => ({
label: t,
value: t,
}))
})
const tagsSelectOption = computed(() => { const tagsSelectOption = computed(() => {
return new List(songsInternal.value) return new List(songsInternal.value)
.SelectMany((s) => new List(s?.tags)) .SelectMany((s) => new List(s?.tags))
@@ -204,14 +216,12 @@ function createColumns(): DataTableColumns<SongsInfo> {
resizable: true, resizable: true,
filterOptions: songSelectOption, filterOptions: songSelectOption,
filter(value, row) { filter(value, row) {
return (row.language?.findIndex((t) => t == (value.toString() as unknown as SongLanguage)) ?? -1) > -1 return (row.language?.findIndex((t) => t == value) ?? -1) > -1
}, },
render(data) { render(data) {
return (data.language?.length ?? 0) > 0 return (data.language?.length ?? 0) > 0
? h(NSpace, { size: 5 }, () => ? h(NSpace, { size: 5 }, () =>
data.language?.map((a) => data.language?.map((a) => h(NTag, { bordered: false, size: 'small' }, () => a)),
h(NTag, { bordered: false, size: 'small' }, () => songSelectOption.find((s) => s.value == a)?.label),
),
) )
: null : null
}, },
@@ -705,7 +715,15 @@ onMounted(() => {
/> />
</NFormItem> </NFormItem>
<NFormItem path="language" label="语言"> <NFormItem path="language" label="语言">
<NSelect v-model:value="updateSongModel.language" multiple :options="songSelectOption" placeholder="可选" /> <NSelect
v-model:value="updateSongModel.language"
filterable
multiple
clearable
tag
placeholder="可选,输入后按回车新增"
:options="languageSelectOption"
/>
</NFormItem> </NFormItem>
<NFormItem path="tags" label="标签"> <NFormItem path="tags" label="标签">
<NSelect <NSelect
@@ -844,7 +862,15 @@ onMounted(() => {
<NButton @click="batchUpdateTag" type="success"> 更新 </NButton> <NButton @click="batchUpdateTag" type="success"> 更新 </NButton>
</NTabPane> </NTabPane>
<NTabPane name="language" tab="语言"> <NTabPane name="language" tab="语言">
<NSelect v-model:value="batchUpdate_Language" multiple :options="songSelectOption" placeholder="选择" /> <NSelect
v-model:value="batchUpdate_Language"
filterable
multiple
clearable
tag
placeholder="可选,输入后按回车新增"
:options="languageSelectOption"
/>
<NDivider /> <NDivider />
<NButton @click="batchUpdateLanguage" type="success"> 更新 </NButton> <NButton @click="batchUpdateLanguage" type="success"> 更新 </NButton>
</NTabPane> </NTabPane>

View File

@@ -155,7 +155,7 @@ const templates = ref({
description: '这是一段描述', description: '这是一段描述',
url: 'https://example.com/song1.mp3', url: 'https://example.com/song1.mp3',
from: SongFrom.Custom, from: SongFrom.Custom,
language: [SongLanguage.Chinese], language: ['中文'],
createTime: Date.now(), createTime: Date.now(),
updateTime: Date.now(), updateTime: Date.now(),
}, },
@@ -167,7 +167,7 @@ const templates = ref({
tags: ['标签1', '标签2'], tags: ['标签1', '标签2'],
url: 'https://example.com/song2.mp3', url: 'https://example.com/song2.mp3',
from: SongFrom.Custom, from: SongFrom.Custom,
language: [SongLanguage.Chinese], language: ['中文'],
createTime: Date.now(), createTime: Date.now(),
updateTime: Date.now(), updateTime: Date.now(),
description: '这还是一段描述', description: '这还是一段描述',
@@ -186,7 +186,7 @@ const templates = ref({
url: 'https://example.com/song3.mp3', url: 'https://example.com/song3.mp3',
from: SongFrom.Custom, from: SongFrom.Custom,
description: '这是一段很长很长很长很长很长很长很长很长很长很长的描述', description: '这是一段很长很长很长很长很长很长很长很长很长很长的描述',
language: [SongLanguage.Chinese], language: ['中文'],
createTime: Date.now(), createTime: Date.now(),
updateTime: Date.now(), updateTime: Date.now(),
}, },
@@ -197,7 +197,7 @@ const templates = ref({
author: ['作者4'], author: ['作者4'],
url: 'https://example.com/song4.mp3', url: 'https://example.com/song4.mp3',
from: SongFrom.Custom, from: SongFrom.Custom,
language: [SongLanguage.Chinese], language: ['中文'],
createTime: Date.now(), createTime: Date.now(),
updateTime: Date.now(), updateTime: Date.now(),
}, },
@@ -209,7 +209,7 @@ const templates = ref({
tags: ['标签1', '标签5', '标签6', '标签7', '标签8', '标签9', '标签10'], tags: ['标签1', '标签5', '标签6', '标签7', '标签8', '标签9', '标签10'],
url: 'https://example.com/song5.mp3', url: 'https://example.com/song5.mp3',
from: SongFrom.Custom, from: SongFrom.Custom,
language: [SongLanguage.Chinese], language: ['中文'],
createTime: Date.now(), createTime: Date.now(),
updateTime: Date.now(), updateTime: Date.now(),
}, },

View File

@@ -152,7 +152,18 @@ const songSelectOption = [
value: SongLanguage.Other, value: SongLanguage.Other,
}, },
] ]
const languageSelectOption = computed(() => {
const languages = new Set<string>(songSelectOption.map((s) => s.label))
songs.value.forEach((s) => {
if (s.language) {
s.language.forEach((l) => languages.add(l))
}
})
return [...languages].map((t) => ({
label: t,
value: t,
}))
})
const uploadFiles = ref<UploadFileInfo[]>([]) const uploadFiles = ref<UploadFileInfo[]>([])
const uploadSongsFromFile = ref<SongsInfo[]>([]) const uploadSongsFromFile = ref<SongsInfo[]>([])
const uploadSongsOptions = computed(() => { const uploadSongsOptions = computed(() => {
@@ -424,7 +435,7 @@ function exportData() {
更新于: format(s.updateTime, 'yyyy-MM-dd HH:mm:ss'), 更新于: format(s.updateTime, 'yyyy-MM-dd HH:mm:ss'),
描述: s.description, 描述: s.description,
来自: from(s.from), 来自: from(s.from),
语言: s.language.map((l) => songSelectOption.find((o) => o.value == l)?.label).join(','), 语言: s.language.join(','),
标签: s.tags?.join(',') ?? '', 标签: s.tags?.join(',') ?? '',
链接: s.url, 链接: s.url,
})), })),
@@ -500,28 +511,12 @@ function parseExcelFile() {
break break
case 'language': case 'language':
case '语言': case '语言':
switch (value) { song.language = value
case '中文': ?.replace('', '/')
case '汉语': .replace('', ',')
song.language = [SongLanguage.Chinese] .split(/\/|,/)
break .map((a: string) => a.trim())
case '英文': .filter((value: string, index: number, self: string[]) => self.indexOf(value) === index)
case '英语':
song.language = [SongLanguage.English]
break
case '日文':
case '日语':
song.language = [SongLanguage.Japanese]
break
case '法语':
song.language = [SongLanguage.French]
break
case '西语':
song.language = [SongLanguage.Spanish]
break
default:
song.language = [SongLanguage.Other]
}
break break
case 'tags': case 'tags':
case 'tag': case 'tag':
@@ -643,9 +638,12 @@ onMounted(async () => {
<NFormItem path="language" label="语言"> <NFormItem path="language" label="语言">
<NSelect <NSelect
v-model:value="addSongModel.language" v-model:value="addSongModel.language"
filterable
multiple multiple
clearable
tag
placeholder="可选,输入后按回车新增"
:options="songSelectOption" :options="songSelectOption"
placeholder="可选"
/> />
</NFormItem> </NFormItem>
<NFormItem path="tags" label="标签"> <NFormItem path="tags" label="标签">