mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-06 08:06:43 +08:00
fix: keep manual reorganize preview visible on partial failures (#470)
This commit is contained in:
@@ -459,12 +459,35 @@ function previewHasFailures(data?: ManualTransferPreviewData) {
|
|||||||
return (data.summary.failed ?? 0) > 0 || (data.items ?? []).some(item => item.success === false)
|
return (data.summary.failed ?? 0) > 0 || (data.items ?? []).some(item => item.success === false)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPreviewFailureMessage(data?: ManualTransferPreviewData) {
|
function getPreviewResultSummaryMessage(data?: ManualTransferPreviewData) {
|
||||||
return (
|
const success = data?.summary.success ?? 0
|
||||||
data?.items.find(item => item.success === false)?.message ||
|
const failed = data?.summary.failed ?? 0
|
||||||
data?.message ||
|
|
||||||
t('dialog.reorganize.previewRequestFailed')
|
return [
|
||||||
)
|
t('dialog.reorganize.previewSuccess', { count: success }),
|
||||||
|
t('dialog.reorganize.previewFailed', { count: failed }),
|
||||||
|
].join(',')
|
||||||
|
}
|
||||||
|
|
||||||
|
function createFailedPreviewData(options: { source?: string; type?: string; title?: string; message?: string }) {
|
||||||
|
const failedItem: ManualTransferPreviewItem = {
|
||||||
|
source: options.source,
|
||||||
|
target: '',
|
||||||
|
success: false,
|
||||||
|
message: options.message || t('dialog.reorganize.previewRequestFailed'),
|
||||||
|
type: options.type,
|
||||||
|
title: options.title,
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
summary: {
|
||||||
|
total: 1,
|
||||||
|
success: 0,
|
||||||
|
failed: 1,
|
||||||
|
},
|
||||||
|
items: [failedItem],
|
||||||
|
message: failedItem.message,
|
||||||
|
} satisfies ManualTransferPreviewData
|
||||||
}
|
}
|
||||||
|
|
||||||
// 合并多次预览结果
|
// 合并多次预览结果
|
||||||
@@ -511,13 +534,31 @@ async function previewTransfer() {
|
|||||||
const result = await requestManualTransfer<ManualTransferPreviewData>(
|
const result = await requestManualTransfer<ManualTransferPreviewData>(
|
||||||
createTransferPayload({ item, preview: true }),
|
createTransferPayload({ item, preview: true }),
|
||||||
)
|
)
|
||||||
if (!result.success) throw new Error(result.message || t('dialog.reorganize.previewRequestFailed'))
|
if (!result.success) {
|
||||||
|
mergePreviewData(
|
||||||
|
mergedPreviewData,
|
||||||
|
createFailedPreviewData({
|
||||||
|
source: item.path || item.name,
|
||||||
|
type: item.type,
|
||||||
|
title: item.name,
|
||||||
|
message: result.message || t('dialog.reorganize.previewRequestFailed'),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
mergePreviewData(mergedPreviewData, result.data)
|
mergePreviewData(mergedPreviewData, result.data)
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.warn(`预览请求异常: ${err?.message}`)
|
console.warn(`预览请求异常: ${err?.message}`)
|
||||||
const label = item.name || item.path
|
mergePreviewData(
|
||||||
throw new Error(`${label}: ${err?.message || t('dialog.reorganize.previewRequestFailed')}`)
|
mergedPreviewData,
|
||||||
|
createFailedPreviewData({
|
||||||
|
source: item.path || item.name,
|
||||||
|
type: item.type,
|
||||||
|
title: item.name,
|
||||||
|
message: `${item.name || item.path}: ${err?.message || t('dialog.reorganize.previewRequestFailed')}`,
|
||||||
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@@ -530,12 +571,27 @@ async function previewTransfer() {
|
|||||||
const result = await requestManualTransfer<ManualTransferPreviewData>(
|
const result = await requestManualTransfer<ManualTransferPreviewData>(
|
||||||
createTransferPayload({ logid, preview: true }),
|
createTransferPayload({ logid, preview: true }),
|
||||||
)
|
)
|
||||||
if (!result.success) throw new Error(result.message || t('dialog.reorganize.previewRequestFailed'))
|
if (!result.success) {
|
||||||
|
mergePreviewData(
|
||||||
|
mergedPreviewData,
|
||||||
|
createFailedPreviewData({
|
||||||
|
source: `历史记录 ${logid}`,
|
||||||
|
message: result.message || t('dialog.reorganize.previewRequestFailed'),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
mergePreviewData(mergedPreviewData, result.data)
|
mergePreviewData(mergedPreviewData, result.data)
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.warn(`预览请求异常: ${err?.message}`)
|
console.warn(`预览请求异常: ${err?.message}`)
|
||||||
throw new Error(`历史记录 ${logid}: ${err?.message || t('dialog.reorganize.previewRequestFailed')}`)
|
mergePreviewData(
|
||||||
|
mergedPreviewData,
|
||||||
|
createFailedPreviewData({
|
||||||
|
source: `历史记录 ${logid}`,
|
||||||
|
message: `历史记录 ${logid}: ${err?.message || t('dialog.reorganize.previewRequestFailed')}`,
|
||||||
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@@ -543,13 +599,13 @@ async function previewTransfer() {
|
|||||||
|
|
||||||
await Promise.all(tasks)
|
await Promise.all(tasks)
|
||||||
|
|
||||||
if (previewHasFailures(mergedPreviewData)) {
|
|
||||||
throw new Error(getPreviewFailureMessage(mergedPreviewData))
|
|
||||||
}
|
|
||||||
|
|
||||||
previewData.value = mergedPreviewData
|
previewData.value = mergedPreviewData
|
||||||
previewLoaded.value = true
|
previewLoaded.value = true
|
||||||
nextTick(() => updatePreviewPageSize())
|
nextTick(() => updatePreviewPageSize())
|
||||||
|
|
||||||
|
if (previewHasFailures(mergedPreviewData)) {
|
||||||
|
$toast.warning(getPreviewResultSummaryMessage(mergedPreviewData))
|
||||||
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
previewVisible.value = false
|
previewVisible.value = false
|
||||||
resetPreviewState()
|
resetPreviewState()
|
||||||
@@ -1021,6 +1077,7 @@ onUnmounted(() => {
|
|||||||
v-for="(item, index) in pagedPreviewRows"
|
v-for="(item, index) in pagedPreviewRows"
|
||||||
:key="`${item.source}-${item.target}-${index}`"
|
:key="`${item.source}-${item.target}-${index}`"
|
||||||
class="preview-file-row"
|
class="preview-file-row"
|
||||||
|
:class="{ 'preview-file-row--failed': item.success === false }"
|
||||||
>
|
>
|
||||||
<div class="preview-file-row__card preview-file-row__card--source">
|
<div class="preview-file-row__card preview-file-row__card--source">
|
||||||
<span class="preview-file-row__label">{{ t('dialog.reorganize.previewBeforeColumn') }}</span>
|
<span class="preview-file-row__label">{{ t('dialog.reorganize.previewBeforeColumn') }}</span>
|
||||||
@@ -1034,6 +1091,9 @@ onUnmounted(() => {
|
|||||||
<span class="preview-file-row__label">{{ t('dialog.reorganize.previewAfterColumn') }}</span>
|
<span class="preview-file-row__label">{{ t('dialog.reorganize.previewAfterColumn') }}</span>
|
||||||
<span class="preview-file-row__name">{{ item.targetName }}</span>
|
<span class="preview-file-row__name">{{ item.targetName }}</span>
|
||||||
<span class="preview-file-row__path">{{ item.target || '-' }}</span>
|
<span class="preview-file-row__path">{{ item.target || '-' }}</span>
|
||||||
|
<span v-if="item.success === false && item.message" class="preview-file-row__message">
|
||||||
|
{{ item.message }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1227,13 +1287,13 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.preview-note {
|
.preview-note {
|
||||||
border: 1px solid rgba(var(--v-theme-info), 0.16);
|
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
||||||
border-radius: 0.875rem;
|
border-radius: 1rem;
|
||||||
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
|
color: rgb(var(--v-theme-error));
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
padding-block: 0.75rem;
|
padding-block: 0.875rem;
|
||||||
padding-inline: 0.875rem;
|
padding-inline: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.preview-summary-grid {
|
.preview-summary-grid {
|
||||||
@@ -1340,6 +1400,10 @@ onUnmounted(() => {
|
|||||||
border-block-start: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
border-block-start: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.preview-file-row--failed {
|
||||||
|
background: rgba(var(--v-theme-error), 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
.preview-file-row__card {
|
.preview-file-row__card {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -1375,6 +1439,16 @@ onUnmounted(() => {
|
|||||||
color: rgb(var(--v-theme-primary));
|
color: rgb(var(--v-theme-primary));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.preview-file-row--failed .preview-file-row__card--target .preview-file-row__name {
|
||||||
|
color: rgb(var(--v-theme-error));
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-file-row__message {
|
||||||
|
color: rgb(var(--v-theme-error));
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
.preview-file-row__arrow {
|
.preview-file-row__arrow {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
Reference in New Issue
Block a user