feat: add tiered storage guard (Green/Yellow/Red) and dashboard queue monitor
Storage Tier System: - Add StorageTier enum (Green >30% / Yellow 10-30% / Red <10%) - Extend StorageGuardResult with Tier, CanStartNewRecording, ShouldPauseActive, UsagePercent - Yellow tier: deny new recordings but allow existing to finish and upload - Red tier: deny new recordings and pause active sessions - Auto-recovery: when disk frees up, polling automatically resumes new recordings - Update LiveRoomPollingBackgroundService to use tier-based checks - Expose tier + usage percent in Recovery API Dashboard Queue Monitor: - Add pending transcode count, pending upload count, queued data volume to dashboard - Add storage tier badge (Green/Yellow/Red) with usage percentage - Add queue monitoring card to dashboard view Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
This commit is contained in:
co-authored by
Claude Opus 4.8 noreply@anthropic.com
parent
cbee29bef9
commit
24e5cf2a06
@@ -823,12 +823,17 @@ export interface DashboardData {
|
||||
storageStatus: DashboardStorageStatus;
|
||||
recentSessions: DashboardRecentSession[];
|
||||
topRooms: DashboardTopRoom[];
|
||||
pendingTranscodeCount: number;
|
||||
pendingUploadCount: number;
|
||||
queuedDataBytes: number;
|
||||
}
|
||||
|
||||
export interface DashboardStorageStatus {
|
||||
hasEnoughSpace: boolean;
|
||||
message: string;
|
||||
availableBytes: number;
|
||||
tier: string;
|
||||
usagePercent: number;
|
||||
}
|
||||
|
||||
export interface DashboardRecentSession {
|
||||
|
||||
@@ -39,6 +39,20 @@ function sessionStatusTagType(status: number) {
|
||||
return "warning";
|
||||
}
|
||||
|
||||
function storageTierTagType(): "success" | "warning" | "danger" {
|
||||
const tier = data.value?.storageStatus.tier;
|
||||
if (tier === "Green") return "success";
|
||||
if (tier === "Yellow") return "warning";
|
||||
return "danger";
|
||||
}
|
||||
|
||||
function storageTierLabel(): string {
|
||||
const tier = data.value?.storageStatus.tier;
|
||||
if (tier === "Green") return "正常";
|
||||
if (tier === "Yellow") return "警告";
|
||||
return "紧急";
|
||||
}
|
||||
|
||||
async function loadData() {
|
||||
loading.value = true;
|
||||
loadError.value = "";
|
||||
@@ -109,11 +123,15 @@ onMounted(loadData);
|
||||
<p class="section-subtitle">录制输出路径的磁盘剩余空间和当前录制保护阈值。</p>
|
||||
<div class="storage-bar-row">
|
||||
<div class="storage-bar-card">
|
||||
<span class="storage-bar-card__label">状态</span>
|
||||
<el-tag :type="data.storageStatus.hasEnoughSpace ? 'success' : 'danger'">
|
||||
{{ data.storageStatus.hasEnoughSpace ? "充足" : "不足" }}
|
||||
<span class="storage-bar-card__label">水位线</span>
|
||||
<el-tag :type="storageTierTagType()" size="large">
|
||||
{{ storageTierLabel() }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<div class="storage-bar-card">
|
||||
<span class="storage-bar-card__label">使用率</span>
|
||||
<span class="storage-bar-card__value">{{ data.storageStatus.usagePercent.toFixed(1) }}%</span>
|
||||
</div>
|
||||
<div class="storage-bar-card">
|
||||
<span class="storage-bar-card__label">可用空间</span>
|
||||
<span class="storage-bar-card__value">{{ formatDataSize(data.storageStatus.availableBytes) }}</span>
|
||||
@@ -125,6 +143,36 @@ onMounted(loadData);
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- Queue Status -->
|
||||
<el-row :gutter="18">
|
||||
<el-col :lg="12" :sm="24">
|
||||
<el-card class="surface-card" shadow="never">
|
||||
<h3 class="section-title">处理队列</h3>
|
||||
<p class="section-subtitle">待转码和待上传的文件积压情况。</p>
|
||||
<div class="storage-bar-row">
|
||||
<div class="storage-bar-card">
|
||||
<span class="storage-bar-card__label">待转码</span>
|
||||
<span class="storage-bar-card__value" :style="{ color: data.pendingTranscodeCount > 0 ? 'var(--warning)' : 'var(--text-primary)' }">
|
||||
{{ data.pendingTranscodeCount }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="storage-bar-card">
|
||||
<span class="storage-bar-card__label">待上传</span>
|
||||
<span class="storage-bar-card__value" :style="{ color: data.pendingUploadCount > 0 ? 'var(--warning)' : 'var(--text-primary)' }">
|
||||
{{ data.pendingUploadCount }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="storage-bar-card">
|
||||
<span class="storage-bar-card__label">积压数据量</span>
|
||||
<span class="storage-bar-card__value" :style="{ color: data.queuedDataBytes > 0 ? 'var(--warning)' : 'var(--text-primary)' }">
|
||||
{{ formatDataSize(data.queuedDataBytes) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- Recent Sessions + Top Rooms -->
|
||||
<el-row :gutter="18">
|
||||
<el-col :lg="12" :sm="24">
|
||||
|
||||
Reference in New Issue
Block a user