Skip to content

Commit 258ae65

Browse files
author
Taois
committed
feat:修复activeKey问题推荐数据不显示问题
1 parent 1345f04 commit 258ae65

File tree

4 files changed

+253
-47
lines changed

4 files changed

+253
-47
lines changed

dashboard/src/api/services/video.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,24 @@ class VideoService {
4949

5050
const { apiUrl, ...otherOptions } = options
5151
const cacheKey = `home_${module}_${JSON.stringify(options)}`
52+
console.log('[VideoService] getRecommendVideos 缓存检查:', {
53+
module,
54+
cacheKey,
55+
cacheSize: this.cache.size,
56+
allCacheKeys: Array.from(this.cache.keys())
57+
});
58+
5259
const cached = this.getFromCache(cacheKey)
5360
if (cached) {
61+
console.log('[VideoService] 使用缓存数据:', {
62+
module,
63+
videosCount: cached.videos?.length || 0,
64+
categoriesCount: cached.categories?.length || 0
65+
});
5466
return cached
5567
}
68+
69+
console.log('[VideoService] 缓存未命中,发起新请求:', module);
5670

5771
try {
5872
const requestOptions = { ...otherOptions }
@@ -69,6 +83,13 @@ class VideoService {
6983
pagination: this.createPagination(response)
7084
}
7185

86+
console.log('[VideoService] 新数据已获取并缓存:', {
87+
module,
88+
videosCount: result.videos?.length || 0,
89+
categoriesCount: result.categories?.length || 0,
90+
cacheKey
91+
});
92+
7293
this.setCache(cacheKey, result)
7394
return result
7495
} catch (error) {

dashboard/src/components/VideoGrid.vue

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,22 @@ const emit = defineEmits(['load-more', 'scroll-bottom', 'refresh-list', 'special
148148
149149
const router = useRouter();
150150
const visitedStore = useVisitedStore();
151+
152+
153+
154+
155+
151156
const containerRef = ref(null);
152157
const scrollbarRef = ref(null);
153158
// 使用非响应式变量避免递归更新
154159
let containerHeight = 600; // 默认高度
155160
const containerHeightTrigger = ref(0); // 仅用于触发重新计算
156161
162+
// 添加内容高度检测相关变量
163+
let contentHeight = 0;
164+
let isContentHeightChecking = false;
165+
let autoLoadTimer = null;
166+
157167
// 计算属性:容器样式
158168
const containerStyle = computed(() => {
159169
// 触发器确保在需要时重新计算
@@ -164,6 +174,88 @@ const containerStyle = computed(() => {
164174
};
165175
});
166176
177+
// 检测内容高度并智能调整容器高度
178+
const checkContentHeight = () => {
179+
if (isContentHeightChecking || isProcessing) return;
180+
181+
isContentHeightChecking = true;
182+
183+
nextTick(() => {
184+
try {
185+
const container = containerRef.value;
186+
if (!container) return;
187+
188+
// 获取实际内容高度
189+
const scrollContainer = container.querySelector('.arco-scrollbar-container');
190+
if (!scrollContainer) return;
191+
192+
contentHeight = scrollContainer.scrollHeight;
193+
const clientHeight = scrollContainer.clientHeight;
194+
195+
// 如果内容高度小于等于容器高度,说明无法产生滚动
196+
if (contentHeight <= clientHeight && props.videos && props.videos.length > 0) {
197+
// 检查是否还有更多数据可以加载
198+
const hasMoreData = props.hasMore !== false;
199+
200+
if (hasMoreData) {
201+
// 减小容器高度以强制产生滚动条,但不能太小
202+
const minHeight = Math.min(400, contentHeight - 50);
203+
if (minHeight > 200 && containerHeight > minHeight) {
204+
containerHeight = minHeight;
205+
containerHeightTrigger.value++;
206+
207+
console.log('[DEBUG] 调整容器高度以产生滚动条:', {
208+
contentHeight,
209+
clientHeight,
210+
newContainerHeight: containerHeight
211+
});
212+
213+
// 延迟检查是否需要自动加载更多
214+
if (autoLoadTimer) clearTimeout(autoLoadTimer);
215+
autoLoadTimer = setTimeout(() => {
216+
checkAutoLoadMore();
217+
}, 500);
218+
} else {
219+
// 如果容器已经很小了,直接触发加载更多
220+
console.log('[DEBUG] 容器已达最小高度,直接触发加载更多');
221+
checkAutoLoadMore();
222+
}
223+
} else {
224+
console.log('[DEBUG] 没有更多数据可加载,保持当前状态');
225+
}
226+
}
227+
} catch (error) {
228+
console.error('checkContentHeight error:', error);
229+
} finally {
230+
isContentHeightChecking = false;
231+
}
232+
});
233+
};
234+
235+
// 检查是否需要自动加载更多数据
236+
const checkAutoLoadMore = () => {
237+
if (isProcessing || updateCount >= MAX_UPDATES_PER_SECOND) return;
238+
239+
try {
240+
const container = containerRef.value;
241+
if (!container) return;
242+
243+
const scrollContainer = container.querySelector('.arco-scrollbar-container');
244+
if (!scrollContainer) return;
245+
246+
const scrollHeight = scrollContainer.scrollHeight;
247+
const clientHeight = scrollContainer.clientHeight;
248+
249+
// 如果内容高度仍然小于等于容器高度,且有更多数据,自动触发加载
250+
if (scrollHeight <= clientHeight && props.videos && props.videos.length > 0) {
251+
console.log('[DEBUG] 自动触发加载更多数据 - 内容高度不足');
252+
emit('load-more');
253+
}
254+
} catch (error) {
255+
console.error('checkAutoLoadMore error:', error);
256+
}
257+
};
258+
167259
// ActionRenderer相关
168260
const actionRendererRef = ref(null);
169261
const showActionRenderer = ref(false);
@@ -402,6 +494,11 @@ onMounted(() => {
402494
containerHeight = currentHeight;
403495
containerHeightTrigger.value++;
404496
}
497+
498+
// 延迟检查内容高度,确保数据已经渲染
499+
setTimeout(() => {
500+
checkContentHeight();
501+
}, 1000);
405502
}
406503
} catch (error) {
407504
console.warn('Initial update failed:', error);
@@ -446,6 +543,11 @@ if (ENABLE_BASIC_UPDATES) {
446543
onBeforeUnmount(() => {
447544
window.removeEventListener('resize', updateScrollAreaHeight);
448545
546+
// 清理定时器
547+
if (autoLoadTimer) {
548+
clearTimeout(autoLoadTimer);
549+
}
550+
449551
// 清理MutationObserver
450552
if (containerRef.value?._filterObserver) {
451553
containerRef.value._filterObserver.disconnect();
@@ -494,6 +596,8 @@ watch([() => props.videos, () => props.showStats], ([newVideos, newShowStats]) =
494596
if (!isProcessing && containerRef.value && !DISABLE_COMPLEX_UPDATES) {
495597
// 只记录日志,不进行DOM操作
496598
console.log('Videos updated:', newVideos.length);
599+
// 检查内容高度
600+
checkContentHeight();
497601
}
498602
}, 300); // 增加延迟时间
499603
@@ -552,7 +656,9 @@ const handleSpecialAction = (actionType, actionData) => {
552656
defineExpose({
553657
checkTextOverflow,
554658
restoreScrollPosition,
555-
getCurrentScrollPosition
659+
getCurrentScrollPosition,
660+
checkContentHeight,
661+
checkAutoLoadMore
556662
});
557663
</script>
558664

dashboard/src/components/VideoList.vue

Lines changed: 66 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,15 @@
7575

7676
<!-- 推荐分类内容 -->
7777
<div v-else-if="activeKey === 'recommendTuijian404'" class="tab-content">
78+
7879
<!-- 分类数据获取loading -->
7980
<div v-if="loadingCategory[activeKey]" class="category-loading-container">
8081
<a-spin :size="24" />
8182
<div class="loading-text">正在加载分类数据...</div>
8283
</div>
84+
8385
<VideoGrid
84-
v-else
86+
v-if="!loadingCategory[activeKey]"
8587
:videos="listData[activeKey] || []"
8688
:loading="loadingMore[activeKey] || false"
8789
:hasMore="false"
@@ -422,7 +424,13 @@ const getListData = async (key, forceReload = false) => {
422424
console.log(`分类 ${key} 正在加载中,跳过重复请求`);
423425
return;
424426
}
425-
427+
428+
console.log('listData.hasOwnProperty(key):', listData.hasOwnProperty(key));
429+
console.log('forceReload:', forceReload);
430+
console.log('listData keys:', Object.keys(listData));
431+
console.log('listData[key]:', listData[key]);
432+
console.log('listData[key] length:', listData[key]?.length);
433+
426434
if (!listData.hasOwnProperty(key) || forceReload) {
427435
// 设置分类数据获取loading状态
428436
loadingCategory[key] = true;
@@ -433,9 +441,11 @@ const getListData = async (key, forceReload = false) => {
433441
let videoList, pagination;
434442
if (key === "recommendTuijian404") {
435443
// 使用传入的推荐视频数据 - 首页推荐数据不允许翻页
444+
console.log('recommendTuijian404 recommendVideos:',props.recommendVideos);
436445
videoList = props.recommendVideos || [];
437446
// 推荐视频数据不允许翻页
438447
pagination = { page: 1, hasNext: false };
448+
439449
} else {
440450
// 获取分类视频,包含筛选参数
441451
const filters = selectedFilters[key] || {};
@@ -460,10 +470,12 @@ const getListData = async (key, forceReload = false) => {
460470
}
461471
}
462472
463-
// 使用批量更新,减少响应式触发次数
464-
Object.assign(listData, { [key]: videoList });
465-
Object.assign(pageData, { [key]: pagination });
466-
Object.assign(loadingMore, { [key]: false });
473+
// 使用直接赋值确保响应式更新
474+
listData[key] = [...videoList];
475+
pageData[key] = pagination;
476+
loadingMore[key] = false;
477+
478+
467479
468480
// 更新全局翻页统计信息
469481
if (key === activeKey.value) {
@@ -682,41 +694,29 @@ const selectCategory = (categoryId) => {
682694
debouncedUpdateStats(getStatsText(categoryId, folderInfo), 100);
683695
};
684696
685-
// 添加防护变量避免递归更新
686-
let isWatchUpdating = false;
687-
688697
// 监听器
689698
watch(() => props.recommendVideos, (newVideos) => {
690-
if (isWatchUpdating) return; // 防止递归更新
699+
console.log('[VideoList] recommendVideos watch triggered:', newVideos?.length);
691700
692-
isWatchUpdating = true;
693-
try {
694-
if (newVideos && newVideos.length > 0) {
695-
listData["recommendTuijian404"] = newVideos;
696-
pageData["recommendTuijian404"] = { page: 1, hasNext: false };
697-
loadingMore["recommendTuijian404"] = false;
698-
console.log("推荐数据已更新:", newVideos.length, "");
699-
} else {
700-
listData["recommendTuijian404"] = [];
701-
pageData["recommendTuijian404"] = { page: 1, hasNext: false };
702-
loadingMore["recommendTuijian404"] = false;
703-
}
704-
705-
const newActiveKey = getDefaultActiveKey();
706-
if (activeKey.value !== newActiveKey) {
707-
activeKey.value = newActiveKey;
708-
// 延迟调用getListData,避免同步递归
709-
setTimeout(() => {
710-
if (!isWatchUpdating) return;
711-
getListData(newActiveKey);
712-
emit('activeKeyChange', newActiveKey);
713-
}, 50);
714-
}
715-
} finally {
716-
// 延迟重置防护变量
717-
setTimeout(() => {
718-
isWatchUpdating = false;
719-
}, 100);
701+
if (newVideos && newVideos.length > 0) {
702+
// 直接赋值,确保响应式更新
703+
listData["recommendTuijian404"] = [...newVideos];
704+
pageData["recommendTuijian404"] = { page: 1, hasNext: false };
705+
loadingMore["recommendTuijian404"] = false;
706+
loadingCategory["recommendTuijian404"] = false;
707+
console.log("推荐数据已更新:", newVideos.length, "");
708+
} else {
709+
listData["recommendTuijian404"] = [];
710+
pageData["recommendTuijian404"] = { page: 1, hasNext: false };
711+
loadingMore["recommendTuijian404"] = false;
712+
loadingCategory["recommendTuijian404"] = false;
713+
}
714+
715+
// 如果当前activeKey是推荐分类,确保界面更新
716+
if (activeKey.value === "recommendTuijian404") {
717+
console.log('[VideoList] 当前是推荐分类,强制更新界面');
718+
// 触发响应式更新
719+
activeKey.value = "recommendTuijian404";
720720
}
721721
}, { immediate: true });
722722
@@ -812,13 +812,36 @@ watch(() => props.sourceRoute?.query?.activeKey, (newActiveKey) => {
812812
}, { immediate: true });
813813
814814
onMounted(() => {
815-
activeKey.value = getDefaultActiveKey();
815+
// 优先使用父组件传递的activeKey,如果没有则使用默认值
816+
const parentActiveKey = props.sourceRoute?.query?.activeKey;
817+
const targetActiveKey = parentActiveKey || getDefaultActiveKey();
818+
819+
console.log('[DEBUG] VideoList onMounted - parentActiveKey:', parentActiveKey, 'targetActiveKey:', targetActiveKey);
816820
817-
// 始终加载数据,不管是否有returnToActiveKey参数
818-
// 这样可以确保刷新页面时数据能正常显示
819-
getListData(activeKey.value);
821+
activeKey.value = targetActiveKey;
820822
821-
emit('activeKeyChange', activeKey.value);
823+
// 对于推荐分类,确保loading状态正确
824+
if (targetActiveKey === "recommendTuijian404") {
825+
loadingCategory[targetActiveKey] = false;
826+
// 如果已有推荐数据,直接使用,不需要再调用getListData
827+
if (props.recommendVideos && props.recommendVideos.length > 0) {
828+
listData[targetActiveKey] = [...props.recommendVideos];
829+
pageData[targetActiveKey] = { page: 1, hasNext: false };
830+
loadingMore[targetActiveKey] = false;
831+
console.log('[DEBUG] 推荐数据已设置,跳过getListData调用');
832+
} else {
833+
// 如果没有推荐数据,才调用getListData
834+
getListData(activeKey.value);
835+
}
836+
} else {
837+
// 非推荐分类,始终加载数据
838+
getListData(activeKey.value);
839+
}
840+
841+
// 只有当使用默认值时才emit,避免覆盖父组件的activeKey
842+
if (!parentActiveKey) {
843+
emit('activeKeyChange', activeKey.value);
844+
}
822845
});
823846
824847
onBeforeUnmount(() => {

0 commit comments

Comments
 (0)