mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-05 15:36:49 +08:00
@@ -6,6 +6,7 @@ import api from '@/api'
|
|||||||
import { numberValidator } from '@/@validators'
|
import { numberValidator } from '@/@validators'
|
||||||
import { useDisplay } from 'vuetify'
|
import { useDisplay } from 'vuetify'
|
||||||
import ProgressDialog from './ProgressDialog.vue'
|
import ProgressDialog from './ProgressDialog.vue'
|
||||||
|
import { MediaDirectory } from '@/api/types'
|
||||||
|
|
||||||
// 显示器宽度
|
// 显示器宽度
|
||||||
const display = useDisplay()
|
const display = useDisplay()
|
||||||
@@ -20,9 +21,9 @@ const props = defineProps({
|
|||||||
// 定义事件
|
// 定义事件
|
||||||
const emit = defineEmits(['done', 'close'])
|
const emit = defineEmits(['done', 'close'])
|
||||||
|
|
||||||
// 生成1到50季的下拉框选项
|
// 生成1到100季的下拉框选项
|
||||||
const seasonItems = ref(
|
const seasonItems = ref(
|
||||||
Array.from({ length: 51 }, (_, i) => i).map(item => ({
|
Array.from({ length: 101 }, (_, i) => i).map(item => ({
|
||||||
title: `第 ${item} 季`,
|
title: `第 ${item} 季`,
|
||||||
value: item,
|
value: item,
|
||||||
})),
|
})),
|
||||||
@@ -53,7 +54,7 @@ const progressValue = ref(0)
|
|||||||
const transferForm = reactive({
|
const transferForm = reactive({
|
||||||
logid: 0,
|
logid: 0,
|
||||||
path: '',
|
path: '',
|
||||||
target: props.target ?? '',
|
target: props.target ?? null,
|
||||||
tmdbid: null,
|
tmdbid: null,
|
||||||
doubanid: null,
|
doubanid: null,
|
||||||
season: null,
|
season: null,
|
||||||
@@ -67,9 +68,17 @@ const transferForm = reactive({
|
|||||||
scrape: true,
|
scrape: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 所有媒体库目录
|
||||||
|
const libraryDirectories = ref<MediaDirectory[]>([])
|
||||||
|
|
||||||
|
// 目的目录下拉框
|
||||||
|
const targetDirectories = computed(() => {
|
||||||
|
return libraryDirectories.value.map(item => item.path)
|
||||||
|
})
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
transferForm.path = props.path ?? ''
|
transferForm.path = props.path ?? ''
|
||||||
transferForm.target = props.target ?? ''
|
transferForm.target = props.target ?? null
|
||||||
})
|
})
|
||||||
|
|
||||||
// 使用SSE监听加载进度
|
// 使用SSE监听加载进度
|
||||||
@@ -158,8 +167,21 @@ async function loadSystemSettings() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 查询媒体库目录
|
||||||
|
async function loadLibraryDirectories() {
|
||||||
|
try {
|
||||||
|
const result: { [key: string]: any } = await api.get('system/setting/LibraryDirectories')
|
||||||
|
if (result.success && result.data?.value) {
|
||||||
|
libraryDirectories.value = result.data.value
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadSystemSettings()
|
loadSystemSettings()
|
||||||
|
loadLibraryDirectories()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -175,11 +197,12 @@ onMounted(() => {
|
|||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
<VRow>
|
<VRow>
|
||||||
<VCol cols="12" md="8">
|
<VCol cols="12" md="8">
|
||||||
<VTextField
|
<VCombobox
|
||||||
v-model="transferForm.target"
|
v-model="transferForm.target"
|
||||||
|
:items="targetDirectories"
|
||||||
label="目的路径"
|
label="目的路径"
|
||||||
placeholder="留空自动"
|
placeholder="留空自动"
|
||||||
hint="留空将自动整理到媒体库目录"
|
hint="留空将自动匹配目标路径"
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="12" md="4">
|
<VCol cols="12" md="4">
|
||||||
|
|||||||
+11
-23
@@ -54,7 +54,7 @@ function startLoadingProgress() {
|
|||||||
progressEventSource.value = new EventSource(
|
progressEventSource.value = new EventSource(
|
||||||
`${import.meta.env.VITE_API_BASE_URL}system/progress/search?token=${token}`,
|
`${import.meta.env.VITE_API_BASE_URL}system/progress/search?token=${token}`,
|
||||||
)
|
)
|
||||||
progressEventSource.value.onmessage = (event) => {
|
progressEventSource.value.onmessage = event => {
|
||||||
const progress = JSON.parse(event.data)
|
const progress = JSON.parse(event.data)
|
||||||
if (progress) {
|
if (progress) {
|
||||||
progressText.value = progress.text
|
progressText.value = progress.text
|
||||||
@@ -80,34 +80,33 @@ async function fetchData() {
|
|||||||
if (!keyword) {
|
if (!keyword) {
|
||||||
// 查询上次搜索结果
|
// 查询上次搜索结果
|
||||||
dataList.value = await api.get('search/last')
|
dataList.value = await api.get('search/last')
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
startLoadingProgress()
|
startLoadingProgress()
|
||||||
// 优先按TMDBID精确查询
|
// 优先按TMDBID精确查询
|
||||||
if (keyword?.startsWith('tmdb:') || keyword?.startsWith('douban:') || keyword?.startsWith('bangumi:')) {
|
if (keyword?.startsWith('tmdb:') || keyword?.startsWith('douban:') || keyword?.startsWith('bangumi:')) {
|
||||||
const result: {[key: string]: any} = await api.get(`search/media/${keyword}`, {
|
const result: { [key: string]: any } = await api.get(`search/media/${keyword}`, {
|
||||||
params: {
|
params: {
|
||||||
mtype: type,
|
mtype: type,
|
||||||
area,
|
area,
|
||||||
season,
|
season,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if (result.success){
|
if (result.success) {
|
||||||
dataList.value = result.data
|
dataList.value = result.data
|
||||||
} else {
|
} else {
|
||||||
errorDescription.value = result.message
|
errorDescription.value = result.message
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// 按标题模糊查询
|
// 按标题模糊查询
|
||||||
dataList.value = await api.get(`search/title/${keyword}`)
|
dataList.value = await api.get(`search/title/${keyword}`)
|
||||||
}
|
}
|
||||||
stopLoadingProgress()
|
stopLoadingProgress()
|
||||||
|
// 从浏览器历史中删除当前搜索
|
||||||
|
window.history.replaceState(null, '', window.location.pathname)
|
||||||
}
|
}
|
||||||
// 标记已刷新
|
// 标记已刷新
|
||||||
isRefreshed.value = true
|
isRefreshed.value = true
|
||||||
}
|
} catch (error) {
|
||||||
catch (error) {
|
|
||||||
console.error(error)
|
console.error(error)
|
||||||
return Promise.reject(error)
|
return Promise.reject(error)
|
||||||
}
|
}
|
||||||
@@ -120,26 +119,15 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<LoadingBanner
|
<LoadingBanner v-if="!isRefreshed" class="mt-12" :text="progressText" :progress="progressValue" />
|
||||||
v-if="!isRefreshed"
|
|
||||||
class="mt-12"
|
|
||||||
:text="progressText"
|
|
||||||
:progress="progressValue"
|
|
||||||
/>
|
|
||||||
<NoDataFound
|
<NoDataFound
|
||||||
v-if="dataList.length === 0 && isRefreshed"
|
v-if="dataList.length === 0 && isRefreshed"
|
||||||
:error-title="errorTitle"
|
:error-title="errorTitle"
|
||||||
:error-description="errorDescription"
|
:error-description="errorDescription"
|
||||||
/>
|
/>
|
||||||
<div v-if="dataList.length > 0">
|
<div v-if="dataList.length > 0">
|
||||||
<TorrentRowListView
|
<TorrentRowListView v-if="viewType === 'list'" :items="dataList" />
|
||||||
v-if="viewType === 'list'"
|
<TorrentCardListView v-else :items="dataList" />
|
||||||
:items="dataList"
|
|
||||||
/>
|
|
||||||
<TorrentCardListView
|
|
||||||
v-else
|
|
||||||
:items="dataList"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- 视图切换 -->
|
<!-- 视图切换 -->
|
||||||
<VFab
|
<VFab
|
||||||
|
|||||||
@@ -19,9 +19,6 @@ const currentHistory = ref<TransferHistory>()
|
|||||||
// 重新整理IDS
|
// 重新整理IDS
|
||||||
const redoIds = ref<number[]>([])
|
const redoIds = ref<number[]>([])
|
||||||
|
|
||||||
// 重新整理target
|
|
||||||
const redoTarget = ref('')
|
|
||||||
|
|
||||||
// 已选中的数据
|
// 已选中的数据
|
||||||
const selected = ref<TransferHistory[]>([])
|
const selected = ref<TransferHistory[]>([])
|
||||||
|
|
||||||
@@ -271,8 +268,6 @@ async function retransferBatch() {
|
|||||||
currentHistory.value = undefined
|
currentHistory.value = undefined
|
||||||
// 重新整理IDS
|
// 重新整理IDS
|
||||||
redoIds.value = selected.value.map(item => item.id)
|
redoIds.value = selected.value.map(item => item.id)
|
||||||
// 重新整理target
|
|
||||||
redoTarget.value = ''
|
|
||||||
// 打开识别弹窗
|
// 打开识别弹窗
|
||||||
redoDialog.value = true
|
redoDialog.value = true
|
||||||
}
|
}
|
||||||
@@ -286,7 +281,6 @@ const dropdownItems = ref([
|
|||||||
prependIcon: 'mdi-redo-variant',
|
prependIcon: 'mdi-redo-variant',
|
||||||
click: (item: TransferHistory) => {
|
click: (item: TransferHistory) => {
|
||||||
redoIds.value = [item.id]
|
redoIds.value = [item.id]
|
||||||
redoTarget.value = getRootPath(item.dest ?? '', item.type ?? '', item.category ?? '')
|
|
||||||
redoDialog.value = true
|
redoDialog.value = true
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -445,7 +439,6 @@ onMounted(fetchData)
|
|||||||
v-if="redoDialog"
|
v-if="redoDialog"
|
||||||
v-model="redoDialog"
|
v-model="redoDialog"
|
||||||
:logids="redoIds"
|
:logids="redoIds"
|
||||||
:target="redoTarget"
|
|
||||||
@done="
|
@done="
|
||||||
() => {
|
() => {
|
||||||
redoDialog = false
|
redoDialog = false
|
||||||
|
|||||||
Reference in New Issue
Block a user