feat(voicelog): 添加初始加载全部选项并优化加载状态提示

- 新增“加载全部”复选框,允许用户选择页面初始化时是否自动加载数据
- 将加载提示从“正在加载...”细化为“请点击加载数据以开始加载”和“没有更多数据了”
- 引入 `hasUserLoaded` 状态,防止未手动加载时触发自动刷新和滚动加载
- 将用户偏好(是否初始加载全部)保存到 localStorage 以实现记忆功能
This commit is contained in:
2026-02-10 09:05:46 +08:00
parent 5f65ed4874
commit da68cef1c1

View File

@@ -90,6 +90,7 @@
:active-text="activeTxt" :active-text="activeTxt"
:inactive-text="inactiveTxt"> :inactive-text="inactiveTxt">
</el-switch> </el-switch>
<el-checkbox v-model="loadAllOnInit" size="small">加载全部</el-checkbox>
</span> </span>
</div> </div>
</div> </div>
@@ -160,10 +161,13 @@
</el-collapse-item> </el-collapse-item>
</el-collapse> </el-collapse>
<!-- 添加底部加载提示 --> <!-- 添加底部加载提示 -->
<div v-if="hasMore" class="loading-more"> <div v-if="isLoading" class="loading-more">
<el-text type="info"><el-icon class="is-loading"><Loading /></el-icon>正在加载...</el-text> <el-text type="info"><el-icon class="is-loading"><Loading /></el-icon>正在加载...</el-text>
</div> </div>
<div v-else class="no-more"> <div v-else-if="showInitHint" class="no-more">
<el-text type="info">请点击加载数据以开始加载</el-text>
</div>
<div v-else-if="!hasMore" class="no-more">
<el-text type="info">没有更多数据了</el-text> <el-text type="info">没有更多数据了</el-text>
</div> </div>
</div> </div>
@@ -173,7 +177,7 @@
<script setup> <script setup>
import { ref, reactive, computed, watch, onMounted, onUnmounted, inject, nextTick } from 'vue'; import { ref, reactive, computed, watch, onMounted, onUnmounted, inject, nextTick } from 'vue';
import { ElSwitch, ElDatePicker, ElCollapse, ElCollapseItem, ElMessage, ElLoading, ElText } from 'element-plus'; import { ElSwitch, ElDatePicker, ElCollapse, ElCollapseItem, ElMessage, ElLoading, ElText, ElCheckbox } from 'element-plus';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import config from '../../../public/config.js' import config from '../../../public/config.js'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
@@ -199,6 +203,9 @@
const logData = ref({}); const logData = ref({});
const errLogs = ref({}); const errLogs = ref({});
const onlyCorrect = ref(false); const onlyCorrect = ref(false);
const loadAllOnInit = ref(false);
const loadAllOnInitStorageKey = 'voicelog_load_all_on_init';
const hasUserLoaded = ref(false);
const onlyCorrectErr = ref(0); const onlyCorrectErr = ref(0);
const onlyCorrectAll = ref(0); const onlyCorrectAll = ref(0);
@@ -250,6 +257,9 @@
} }
return 2; return 2;
}); });
const showInitHint = computed(() => {
return !hasUserLoaded.value && !isLoading.value && Object.keys(logs.value).length === 0;
});
// 计算属性 filteredLogs // 计算属性 filteredLogs
const filteredLogs = computed(() => { const filteredLogs = computed(() => {
let rs = {}; let rs = {};
@@ -279,9 +289,14 @@
// 监听器 // 监听器
watch(onlyCorrect, (newVal) => { watch(onlyCorrect, (newVal) => {
nextTick(() => { nextTick(() => {
if (hasUserLoaded.value) {
checkNeedMoreData(); checkNeedMoreData();
}
}); });
}); });
watch(loadAllOnInit, (newVal) => {
localStorage.setItem(loadAllOnInitStorageKey, String(!!newVal));
});
// 监听 isMobile 变化 // 监听 isMobile 变化
watch(isMobile, (newVal) => { watch(isMobile, (newVal) => {
// 当切换到桌面端时,强制显示所有控件 // 当切换到桌面端时,强制显示所有控件
@@ -319,6 +334,13 @@
buttonDisabled.value = false; buttonDisabled.value = false;
}, 9999); // 10秒后解除禁用 }, 9999); // 10秒后解除禁用
hasUserLoaded.value = true;
if (!pickerDate.value || !pickerDate.value[0] || !pickerDate.value[1]) {
pickerDate.value = [
dayjs().subtract(1, 'day').toDate(),
dayjs().toDate()
];
}
// 调用原有的加载数据方法 // 调用原有的加载数据方法
showSelectedLogs(); showSelectedLogs();
}; };
@@ -495,7 +517,9 @@
await getLogCount(QueryDate) await getLogCount(QueryDate)
} }
nextTick(() => { nextTick(() => {
if (hasUserLoaded.value) {
checkNeedMoreData(); checkNeedMoreData();
}
}); });
} }
}; };
@@ -624,6 +648,7 @@
} }
refreshTimer.value = setInterval(async () => { refreshTimer.value = setInterval(async () => {
if (!hasUserLoaded.value) return;
if (isAtTop() && roomHotelCode.value.length == 0) { if (isAtTop() && roomHotelCode.value.length == 0) {
await showSelectedLogs(false, true); // 使用 isRefresh=true 调用 await showSelectedLogs(false, true); // 使用 isRefresh=true 调用
} }
@@ -632,10 +657,17 @@
// 生命周期钩子 // 生命周期钩子
onMounted(async () => { onMounted(async () => {
localStorage.setItem('url', '/voicelog'); localStorage.setItem('url', '/voicelog');
const storedLoadAll = localStorage.getItem(loadAllOnInitStorageKey);
if (storedLoadAll !== null) {
loadAllOnInit.value = storedLoadAll === 'true';
}
try { try {
await getAllHotels(); await getAllHotels();
if (loadAllOnInit.value) {
hasUserLoaded.value = true;
await showSelectedLogs(true, true); // 初始加载 await showSelectedLogs(true, true); // 初始加载
}
startAutoRefresh(); // 启动定时刷新 startAutoRefresh(); // 启动定时刷新
} catch (error) { } catch (error) {
console.error('初始化失败:', error); console.error('初始化失败:', error);
@@ -666,6 +698,7 @@
// 滚动处理 // 滚动处理
const handleScroll = (e) => { const handleScroll = (e) => {
if (!hasUserLoaded.value) return;
const container = e.target; const container = e.target;
// 计算距离底部的距离(像素) // 计算距离底部的距离(像素)
@@ -678,6 +711,7 @@
}; };
const checkNeedMoreData = () => { const checkNeedMoreData = () => {
if (!hasUserLoaded.value) return false;
const logContainer = document.querySelector('.log-container'); const logContainer = document.querySelector('.log-container');
if (!logContainer || isLoading.value || !hasMore.value) return false; if (!logContainer || isLoading.value || !hasMore.value) return false;