2026-06-02 08:14:09 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<v-dialog :model-value="modelValue" max-width="800" @update:model-value="$emit('update:modelValue', $event)">
|
|
|
|
|
|
<v-card border>
|
|
|
|
|
|
<v-card-title class="d-flex align-center">
|
|
|
|
|
|
推送预览
|
|
|
|
|
|
<v-spacer />
|
|
|
|
|
|
<span class="text-caption text-medium-emphasis">
|
|
|
|
|
|
<template v-if="loading">{{ previewDone }} / {{ previewTotal }} 台</template>
|
|
|
|
|
|
<template v-else>{{ results.length }} 台</template>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</v-card-title>
|
|
|
|
|
|
<v-card-text>
|
|
|
|
|
|
<v-progress-linear
|
|
|
|
|
|
v-if="loading"
|
|
|
|
|
|
:model-value="previewTotal ? Math.round((previewDone / previewTotal) * 100) : 0"
|
|
|
|
|
|
class="mb-3"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<v-alert
|
|
|
|
|
|
v-if="largeBatch && !loading"
|
|
|
|
|
|
type="info"
|
|
|
|
|
|
density="compact"
|
|
|
|
|
|
variant="tonal"
|
|
|
|
|
|
class="mb-2"
|
|
|
|
|
|
>
|
|
|
|
|
|
已预览 {{ results.length }} 台服务器(超过 {{ warnThreshold }} 台时推送耗时可能较长)
|
|
|
|
|
|
</v-alert>
|
|
|
|
|
|
<div v-if="!loading" class="mb-2 text-body-2">
|
|
|
|
|
|
将推送到 <strong>{{ selectedCount }}</strong> 台服务器
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<v-table v-if="results.length" density="compact">
|
|
|
|
|
|
<thead>
|
|
|
|
|
|
<tr>
|
|
|
|
|
|
<th>服务器</th>
|
|
|
|
|
|
<th>文件数</th>
|
|
|
|
|
|
<th>预计传输</th>
|
|
|
|
|
|
<th>大小</th>
|
|
|
|
|
|
<th>备注</th>
|
|
|
|
|
|
</tr>
|
|
|
|
|
|
</thead>
|
|
|
|
|
|
<tbody>
|
|
|
|
|
|
<tr v-for="row in results" :key="row.server_id">
|
2026-06-12 01:43:51 +08:00
|
|
|
|
<td>
|
|
|
|
|
|
<span class="push-preview-server-name" :title="row.server_name">{{ row.server_name }}</span>
|
|
|
|
|
|
</td>
|
2026-06-02 08:14:09 +08:00
|
|
|
|
<td>{{ row.stats?.files_total ?? '—' }}</td>
|
|
|
|
|
|
<td>{{ row.stats?.files_transferred ?? '—' }}</td>
|
|
|
|
|
|
<td>{{ row.stats ? formatSize(row.stats.transfer_size_bytes ?? 0) : '—' }}</td>
|
|
|
|
|
|
<td>
|
2026-06-02 15:18:01 +08:00
|
|
|
|
<span v-if="row.error" class="text-error text-caption">{{ formatPushErrorMessage(row.error) }}</span>
|
2026-06-02 08:14:09 +08:00
|
|
|
|
<span
|
|
|
|
|
|
v-else-if="syncMode === 'full' && (row.stats?.files_deleted ?? 0) > 0"
|
|
|
|
|
|
class="text-warning text-caption"
|
|
|
|
|
|
>将删除 {{ row.stats?.files_deleted }} 个远端文件</span>
|
|
|
|
|
|
<span v-else class="text-caption text-medium-emphasis">—</span>
|
|
|
|
|
|
</td>
|
|
|
|
|
|
</tr>
|
|
|
|
|
|
</tbody>
|
|
|
|
|
|
</v-table>
|
|
|
|
|
|
<v-alert v-if="errorCount > 0 && !loading" type="warning" density="compact" variant="tonal" class="mt-3">
|
|
|
|
|
|
{{ errorCount }} 台预览失败,推送时这些服务器可能仍会失败
|
|
|
|
|
|
</v-alert>
|
|
|
|
|
|
</v-card-text>
|
|
|
|
|
|
<v-card-actions>
|
|
|
|
|
|
<v-spacer />
|
|
|
|
|
|
<v-btn variant="text" @click="$emit('update:modelValue', false)">关闭</v-btn>
|
|
|
|
|
|
<v-btn color="primary" variant="flat" :disabled="loading" @click="$emit('confirm-push')">确认推送</v-btn>
|
|
|
|
|
|
</v-card-actions>
|
|
|
|
|
|
</v-card>
|
|
|
|
|
|
</v-dialog>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
2026-06-02 15:18:01 +08:00
|
|
|
|
import { formatPushErrorMessage, formatSize } from '@/composables/push/labels'
|
2026-06-02 08:14:09 +08:00
|
|
|
|
import type { PreviewServerRow, SyncMode } from '@/composables/push/types'
|
|
|
|
|
|
|
|
|
|
|
|
defineProps<{
|
|
|
|
|
|
modelValue: boolean
|
|
|
|
|
|
loading: boolean
|
|
|
|
|
|
results: PreviewServerRow[]
|
|
|
|
|
|
selectedCount: number
|
|
|
|
|
|
previewDone: number
|
|
|
|
|
|
previewTotal: number
|
|
|
|
|
|
largeBatch: boolean
|
|
|
|
|
|
warnThreshold: number
|
|
|
|
|
|
errorCount: number
|
|
|
|
|
|
syncMode: SyncMode
|
|
|
|
|
|
}>()
|
|
|
|
|
|
|
|
|
|
|
|
defineEmits<{
|
|
|
|
|
|
'update:modelValue': [value: boolean]
|
|
|
|
|
|
'confirm-push': []
|
|
|
|
|
|
}>()
|
|
|
|
|
|
</script>
|
2026-06-12 01:43:51 +08:00
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.push-preview-server-name {
|
|
|
|
|
|
display: inline-block;
|
|
|
|
|
|
max-width: 220px;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
vertical-align: bottom;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|