feat: harden recording lifecycle and refresh fnOS UI
This commit is contained in:
@@ -7,7 +7,9 @@ import { logLevelLabelMap } from "@/types";
|
||||
|
||||
const AUTO_REFRESH_INTERVAL_MS = 15000;
|
||||
|
||||
const loading = ref(false);
|
||||
const initialLoading = ref(false);
|
||||
const refreshing = ref(false);
|
||||
const requestInFlight = ref(false);
|
||||
const logs = ref<SystemLog[]>([]);
|
||||
const loadError = ref("");
|
||||
const { isMobile } = useViewport();
|
||||
@@ -31,13 +33,25 @@ const newestLogTime = computed(() => (logs.value[0] ? formatDate(logs.value[0].c
|
||||
|
||||
let autoRefreshTimer: number | null = null;
|
||||
|
||||
async function loadLogs() {
|
||||
if (loading.value) {
|
||||
function mergeLogs(nextLogs: SystemLog[]) {
|
||||
const previousById = new Map(logs.value.map((item) => [item.id, item]));
|
||||
return nextLogs.map((item) => {
|
||||
const previous = previousById.get(item.id);
|
||||
return previous && JSON.stringify(previous) === JSON.stringify(item) ? previous : item;
|
||||
});
|
||||
}
|
||||
|
||||
async function loadLogs(background = false) {
|
||||
if (requestInFlight.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
loadError.value = "";
|
||||
requestInFlight.value = true;
|
||||
initialLoading.value = !background && logs.value.length === 0;
|
||||
refreshing.value = !initialLoading.value;
|
||||
if (!background) {
|
||||
loadError.value = "";
|
||||
}
|
||||
|
||||
try {
|
||||
const { data } = await apiClient.get<SystemLog[]>("/logs", {
|
||||
@@ -50,11 +64,13 @@ async function loadLogs() {
|
||||
}
|
||||
});
|
||||
|
||||
logs.value = data;
|
||||
logs.value = mergeLogs(data);
|
||||
} catch (error) {
|
||||
loadError.value = getApiErrorMessage(error, "系统日志加载失败,请稍后重试。");
|
||||
} finally {
|
||||
loading.value = false;
|
||||
requestInFlight.value = false;
|
||||
initialLoading.value = false;
|
||||
refreshing.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +79,7 @@ async function autoRefreshLogs() {
|
||||
return;
|
||||
}
|
||||
|
||||
await loadLogs();
|
||||
await loadLogs(true);
|
||||
}
|
||||
|
||||
function startAutoRefresh() {
|
||||
@@ -126,7 +142,7 @@ onBeforeUnmount(() => {
|
||||
</div>
|
||||
|
||||
<div class="page-toolbar">
|
||||
<el-button @click="loadLogs">刷新日志</el-button>
|
||||
<el-button :loading="refreshing" @click="loadLogs(false)">刷新日志</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -187,7 +203,7 @@ onBeforeUnmount(() => {
|
||||
<el-input-number v-model="filters.take" :min="1" :max="500" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="loadLogs">应用筛选</el-button>
|
||||
<el-button type="primary" @click="loadLogs(false)">应用筛选</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
@@ -230,8 +246,7 @@ onBeforeUnmount(() => {
|
||||
<div v-else class="table-scroll-shell logs-table-shell">
|
||||
<el-table
|
||||
:data="logs"
|
||||
v-loading="loading"
|
||||
:height="720"
|
||||
v-loading="initialLoading"
|
||||
class="premium-table logs-table"
|
||||
table-layout="auto"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user