Files
FileHost/app/components/storage/StorageUsageBar.vue
O96u ac65c1eb9d refactor: 重构设置、API、图库与存储页面前端结构。
将操作日志并入设置侧栏,补齐检查更新提示与版本接口刷新;拆分各模块组件并修复图库搜索分页变量。
2026-09-01 17:15:02 +08:00

89 lines
2.3 KiB
Vue

<script setup lang="ts">
import type { StorageCapacity } from '~/types/storage'
const props = defineProps<{
capacity: StorageCapacity
indexBytes: number
}>()
const { formatFileSize } = useFileSize()
const displayUsedBytes = computed(() =>
props.capacity.source === 'disk' ? props.capacity.usedBytes : props.indexBytes
)
const hasBar = computed(() =>
props.capacity.totalBytes != null && props.capacity.totalBytes > 0
)
const displayPercent = computed(() => props.capacity.percent ?? 0)
const overQuota = computed(() =>
props.capacity.source === 'quota' && displayPercent.value > 100
)
const barWidth = computed(() => {
if (!hasBar.value) return 0
const percent = Math.min(displayPercent.value, 100)
return Math.max(percent, displayUsedBytes.value > 0 ? 4 : 0)
})
function formatOptional(bytes: number | null): string {
if (bytes == null) return '—'
return formatFileSize(bytes)
}
</script>
<template>
<div class="space-y-3">
<div class="grid grid-cols-2 gap-3 sm:grid-cols-4">
<div>
<p class="text-xs text-muted">
{{ $t('storage.statUsed') }}
</p>
<p class="mt-1 text-sm font-semibold tabular-nums">
{{ formatFileSize(displayUsedBytes) }}
</p>
</div>
<div>
<p class="text-xs text-muted">
{{ $t('storage.statTotal') }}
</p>
<p class="mt-1 text-sm font-semibold tabular-nums">
{{ formatOptional(capacity.totalBytes) }}
</p>
</div>
<div>
<p class="text-xs text-muted">
{{ $t('storage.statFree') }}
</p>
<p
class="mt-1 text-sm font-semibold tabular-nums"
:class="overQuota ? 'text-error' : ''"
>
{{ formatOptional(capacity.freeBytes) }}
</p>
</div>
<div>
<p class="text-xs text-muted">
{{ $t('storage.usageRate') }}
</p>
<p class="mt-1 text-sm font-semibold tabular-nums">
{{ hasBar ? `${displayPercent}%` : '—' }}
</p>
</div>
</div>
<div
v-if="hasBar"
class="h-1 overflow-hidden rounded-full bg-muted/50"
>
<div
class="h-full rounded-full transition-all"
:class="overQuota ? 'bg-error/80' : 'bg-primary'"
:style="{ width: `${barWidth}%` }"
/>
</div>
</div>
</template>