From 44f9171313f81842dcfa871165c53ba7201da7a7 Mon Sep 17 00:00:00 2001 From: lanyeeee Date: Sun, 10 Aug 2025 06:13:29 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=95=AA=E5=89=A7=E6=90=9C=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/panes/SearchPane/SearchPane.vue | 69 ++++- .../SearchPane/components/BangumiPanel.vue | 247 ++++++++++++++++++ .../SearchPane/components/EpisodeCard.vue | 28 +- src/utils.tsx | 30 +++ 4 files changed, 364 insertions(+), 10 deletions(-) create mode 100644 src/panes/SearchPane/components/BangumiPanel.vue diff --git a/src/panes/SearchPane/SearchPane.vue b/src/panes/SearchPane/SearchPane.vue index a2a82be..310a4fa 100644 --- a/src/panes/SearchPane/SearchPane.vue +++ b/src/panes/SearchPane/SearchPane.vue @@ -3,17 +3,19 @@ import { computed, ref } from 'vue' import { SelectProps, useMessage } from 'naive-ui' import { PhMagnifyingGlass } from '@phosphor-icons/vue' import FloatLabelInput from '../../components/FloatLabelInput.vue' -import { commands, GetNormalInfoParams, SearchParams, SearchResult } from '../../bindings.ts' +import { commands, GetBangumiInfoParams, GetNormalInfoParams, SearchParams, SearchResult } from '../../bindings.ts' import NormalSeasonPanel from './components/NormalSeasonPanel.vue' import NormalSinglePanel from './components/NormalSinglePanel.vue' -import { extractBvid, extractAid } from '../../utils.tsx' +import { extractBvid, extractAid, extractEpId, extractSeasonId } from '../../utils.tsx' import { useStore } from '../../store.ts' +import BangumiPanel from './components/BangumiPanel.vue' -export type SearchType = 'Auto' | 'Normal' | 'Bangumi' | 'Cheese' +export type SearchType = 'Auto' | 'Normal' | 'Bangumi' const searchTypeOptions: SelectProps['options'] = [ { label: '自动', value: 'Auto' }, { label: '视频', value: 'Normal' }, + { label: '番剧', value: 'Bangumi' }, ] const store = useStore() @@ -28,8 +30,10 @@ const searchResult = ref() const searchLabel = computed(() => { if (searchTypeSelected.value === 'Normal') { return '链接 / av... / BV...' + } else if (searchTypeSelected.value === 'Bangumi') { + return '链接 / ep... / ss...' } - return '链接 / av... / BV... ' + return '链接 / av... / BV... / ep... / ss...' }) async function search(input: string, searchType: SearchType) { @@ -48,6 +52,8 @@ async function search(input: string, searchType: SearchType) { await searchAuto(input, isUrl) } else if (searchType === 'Normal') { await searchNormal(input, isUrl) + } else if (searchType === 'Bangumi') { + await searchBangumi(input, isUrl) } else { message.error('未知的搜索类型') } @@ -60,11 +66,17 @@ async function searchAuto(input: string, isUrl: boolean) { if (isUrl) { const bvid = extractBvid(input) const aid = extractAid(input) + const epId = extractEpId(input) + const seasonId = extractSeasonId(input) if (bvid !== undefined) { params = { Normal: { Bvid: bvid } } } else if (aid !== undefined) { params = { Normal: { Aid: aid } } + } else if (epId !== undefined) { + params = { Bangumi: { EpId: epId } } + } else if (seasonId !== undefined) { + params = { Bangumi: { SeasonId: seasonId } } } } else if (input.toLowerCase().startsWith('bv')) { params = { Normal: { Bvid: input } } @@ -73,10 +85,20 @@ async function searchAuto(input: string, isUrl: boolean) { if (!isNaN(aid)) { params = { Normal: { Aid: aid } } } + } else if (input.toLowerCase().startsWith('ep')) { + const epId = parseInt(input.substring(2), 10) + if (!isNaN(epId)) { + params = { Bangumi: { EpId: epId } } + } + } else if (input.toLowerCase().startsWith('ss')) { + const seasonId = parseInt(input.substring(2), 10) + if (!isNaN(seasonId)) { + params = { Bangumi: { SeasonId: seasonId } } + } } if (params === undefined) { - message.error('解析输入失败,请输入正确的链接或ID(如 av... / BV...)') + message.error('解析输入失败,请输入正确的链接或ID(如 av... / BV... / ep... / ss...)') return } @@ -121,6 +143,42 @@ async function searchNormal(input: string, isUrl: boolean) { searchResult.value = result.data } +async function searchBangumi(input: string, isUrl: boolean) { + let params: GetBangumiInfoParams | undefined + + if (isUrl) { + const epId = extractEpId(input) + const seasonId = extractSeasonId(input) + if (epId !== undefined) { + params = { EpId: epId } + } else if (seasonId !== undefined) { + params = { SeasonId: seasonId } + } + } else if (input.toLowerCase().startsWith('ep')) { + const epId = parseInt(input.substring(2), 10) + if (!isNaN(epId)) { + params = { EpId: epId } + } + } else if (input.toLowerCase().startsWith('ss')) { + const seasonId = parseInt(input.substring(2), 10) + if (!isNaN(seasonId)) { + params = { SeasonId: seasonId } + } + } + + if (params === undefined) { + message.error('解析输入失败,请输入正确的链接或ID(如 ep... / ss...)') + return + } + + const result = await commands.search({ Bangumi: params }) + if (result.status === 'error') { + console.error(result.error) + return + } + searchResult.value = result.data +} + defineExpose({ search }) @@ -158,6 +216,7 @@ defineExpose({ search }) :normal-result="searchResult.Normal" :ugc-season="searchResult.Normal.ugc_season" /> + diff --git a/src/panes/SearchPane/components/BangumiPanel.vue b/src/panes/SearchPane/components/BangumiPanel.vue new file mode 100644 index 0000000..05527d4 --- /dev/null +++ b/src/panes/SearchPane/components/BangumiPanel.vue @@ -0,0 +1,247 @@ + + + + + diff --git a/src/panes/SearchPane/components/EpisodeCard.vue b/src/panes/SearchPane/components/EpisodeCard.vue index 0ae919a..2d0c137 100644 --- a/src/panes/SearchPane/components/EpisodeCard.vue +++ b/src/panes/SearchPane/components/EpisodeCard.vue @@ -1,11 +1,11 @@