feat: harden recording lifecycle and refresh fnOS UI

This commit is contained in:
2026-08-03 23:45:26 +08:00
parent e5b50ea85c
commit ecc737f0bd
90 changed files with 6995 additions and 1826 deletions
+13 -15
View File
@@ -6,6 +6,7 @@ import apiClient, { getApiErrorMessage } from "@/api/client";
import EmptyState from "@/components/ui/EmptyState.vue";
import MetricCard from "@/components/ui/MetricCard.vue";
import StatusBadge from "@/components/ui/StatusBadge.vue";
import StorageCapacity from "@/components/ui/StorageCapacity.vue";
import { useViewport } from "@/composables/useViewport";
import type {
RecoverableFinalization,
@@ -13,8 +14,8 @@ import type {
RecoveryActionResult,
RecoveryOverview
} from "@/types";
import { autoStartDecisionLabelMap, taskStatusLabelMap } from "@/types";
import { RefreshRight, VideoCamera, WarningFilled } from "@element-plus/icons-vue";
import { autoStartDecisionLabelMap, formatAutoStartDecisionSummary, taskStatusLabelMap } from "@/types";
import { RefreshRight, VideoCamera } from "@element-plus/icons-vue";
const loading = ref(false);
const retryAllLoading = ref(false);
@@ -137,6 +138,10 @@ function autoStartDecisionLabel(code?: string) {
return autoStartDecisionLabelMap[code] ?? code;
}
function autoStartDecisionSummary(item: RecoverableLiveRoom) {
return formatAutoStartDecisionSummary(item.lastAutoStartDecisionCode, item.lastAutoStartDecisionSummary);
}
function autoStartDecisionTagType(code?: string) {
if (code === "started") {
return "success";
@@ -188,21 +193,14 @@ onMounted(loadOverview);
<el-alert v-if="loadError" class="page-error-alert" type="error" :closable="false" show-icon :title="loadError" />
<div class="stats-grid recovery-metrics" v-loading="loading">
<MetricCard
label="存储保护"
:value="storage?.hasEnoughSpace ? '可恢复' : '受限'"
:description="storage?.message || '暂无存储数据'"
:icon="WarningFilled"
/>
<MetricCard label="可重试开录" :value="liveRooms.length" description="在线、启用中且没有活动会话的直播间" :icon="RefreshRight" />
<MetricCard label="可恢复转码" :value="finalizations.length" description="等待继续或可手动补转码的 MP4 任务" :icon="VideoCamera" />
<MetricCard
label="剩余空间"
:value="storage ? formatBytes(storage.availableBytes) : '--'"
:description="`恢复阈值 ${storage ? formatBytes(storage.requiredBytes) : '--'}`"
/>
</div>
<el-card v-if="storage" class="surface-card" shadow="never">
<StorageCapacity :status="storage" />
</el-card>
<el-card class="surface-card table-card" shadow="never">
<div class="toolbar-row">
<div>
@@ -254,7 +252,7 @@ onMounted(loadOverview);
</div>
<div>
<dt>最近决策</dt>
<dd>{{ row.lastAutoStartDecisionSummary || "暂无摘要" }}</dd>
<dd>{{ autoStartDecisionSummary(row) }}</dd>
</div>
<div style="grid-column: 1 / -1;" v-if="row.lastAutoStartDecisionDetail">
<dt>原因详情</dt>
@@ -308,7 +306,7 @@ onMounted(loadOverview);
/>
<span class="table-date-text">{{ formatDate(row.lastAutoStartDecisionAt) }}</span>
</div>
<div class="cell-subtitle">{{ row.lastAutoStartDecisionSummary || "暂无自动开录摘要" }}</div>
<div class="cell-subtitle">{{ autoStartDecisionSummary(row) }}</div>
<div v-if="row.lastAutoStartDecisionDetail" class="decision-cell__detail">
{{ row.lastAutoStartDecisionDetail }}
</div>