Skip to content

Commit 439ba4d

Browse files
author
Taois
committed
fix: 修复下面的bug
1. 默认图片不存在会无限请求问题 2. 详情页返回后不是之前的来源分类/搜索页问题 3. 分类或者搜索由于内容没撑起来高度导致的无法翻页问题
1 parent a8ce1c2 commit 439ba4d

File tree

12 files changed

+724
-30
lines changed

12 files changed

+724
-30
lines changed

dashboard/src/App.vue

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,25 @@
66
</template>
77

88
<script>
9+
import { onMounted } from 'vue';
910
import Layout from './components/Layout.vue';
11+
import { useVisitedStore } from './stores/visitedStore';
1012
1113
export default {
1214
name: 'App',
1315
components: {
1416
Layout,
1517
},
18+
setup() {
19+
const visitedStore = useVisitedStore();
20+
21+
// 应用启动时加载访问记录
22+
onMounted(() => {
23+
visitedStore.loadFromStorage();
24+
});
25+
26+
return {};
27+
}
1628
};
1729
</script>
1830

dashboard/src/components/SearchResults.vue

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,13 @@
100100
import { ref, nextTick, onMounted, onBeforeUnmount, watch } from 'vue'
101101
import { useRouter } from 'vue-router'
102102
import { usePaginationStore } from '@/stores/paginationStore'
103+
import { usePageStateStore } from '@/stores/pageStateStore'
104+
import { useVisitedStore } from '@/stores/visitedStore'
103105
104106
const router = useRouter()
105107
const paginationStore = usePaginationStore()
108+
const pageStateStore = usePageStateStore()
109+
const visitedStore = useVisitedStore()
106110
107111
// Props
108112
const props = defineProps({
@@ -133,6 +137,16 @@ const props = defineProps({
133137
hasMore: {
134138
type: Boolean,
135139
default: false
140+
},
141+
// 新增:来源页面信息
142+
sourceRoute: {
143+
type: Object,
144+
default: () => ({})
145+
},
146+
// 新增:滚动位置
147+
scrollPosition: {
148+
type: Number,
149+
default: 0
136150
}
137151
})
138152
@@ -179,7 +193,14 @@ const updateScrollAreaHeight = () => {
179193
const searchHeader = document.querySelector('.search-header');
180194
const headerHeight = searchHeader ? searchHeader.offsetHeight : 60;
181195
182-
const newHeight = Math.max(containerHeight - headerHeight, 400);
196+
// 根据搜索结果动态调整高度减值
197+
// 如果没有结果或结果很少,减去100px强制触发滚动条
198+
// 如果有足够搜索结果,只减去少量padding空间
199+
const hasEnoughContent = props.videos && props.videos.length >= 17;
200+
const heightReduction = hasEnoughContent ? 4 : 100;
201+
202+
const newHeight = Math.max(containerHeight - headerHeight - heightReduction, 400);
203+
console.log(`搜索结果数量: ${props.videos?.length || 0}, 内容充足: ${hasEnoughContent}, 高度减值: ${heightReduction}, 最终高度: ${newHeight}`);
183204
scrollAreaHeight.value = newHeight;
184205
}, 100); // 延迟确保DOM完全渲染
185206
});
@@ -239,6 +260,31 @@ const checkTextOverflow = () => {
239260
// 视频点击处理
240261
const handleVideoClick = (video) => {
241262
if (video && video.vod_id) {
263+
// 记录最后点击的视频
264+
visitedStore.setLastClicked(video.vod_id, video.vod_name)
265+
266+
// 保存当前搜索状态
267+
if (props.keyword) {
268+
// 正确获取滚动位置
269+
const scrollContainer = scrollbarRef.value?.$el?.querySelector('.arco-scrollbar-container');
270+
const currentScrollPosition = scrollContainer?.scrollTop || 0;
271+
272+
pageStateStore.saveSearchState(
273+
props.keyword,
274+
props.currentPage,
275+
props.videos,
276+
props.hasMore,
277+
props.loading,
278+
currentScrollPosition
279+
);
280+
console.log('保存搜索状态:', {
281+
keyword: props.keyword,
282+
currentPage: props.currentPage,
283+
videosCount: props.videos.length,
284+
scrollPosition: currentScrollPosition
285+
});
286+
}
287+
242288
router.push({
243289
name: 'VideoDetail',
244290
params: { id: video.vod_id },
@@ -251,7 +297,12 @@ const handleVideoClick = (video) => {
251297
remarks: video.vod_remarks,
252298
content: video.vod_content,
253299
actor: video.vod_actor,
254-
director: video.vod_director
300+
director: video.vod_director,
301+
// 添加来源页面信息
302+
sourceRouteName: props.sourceRoute?.name,
303+
sourceRouteParams: JSON.stringify(props.sourceRoute?.params || {}),
304+
sourceRouteQuery: JSON.stringify(props.sourceRoute?.query || {}),
305+
fromSearch: 'true' // 标识来自搜索结果
255306
}
256307
});
257308
}
@@ -269,6 +320,24 @@ onMounted(() => {
269320
updateScrollAreaHeight()
270321
updateGlobalStats()
271322
window.addEventListener('resize', updateScrollAreaHeight)
323+
324+
// 恢复滚动位置
325+
if (props.scrollPosition > 0) {
326+
nextTick(() => {
327+
// 使用requestAnimationFrame确保DOM已渲染
328+
requestAnimationFrame(() => {
329+
const scrollContainer = scrollbarRef.value?.$el?.querySelector('.arco-scrollbar-container');
330+
if (scrollContainer) {
331+
// 使用平滑滚动
332+
scrollContainer.scrollTo({
333+
top: props.scrollPosition,
334+
behavior: 'smooth'
335+
});
336+
console.log('SearchResults恢复滚动位置:', props.scrollPosition);
337+
}
338+
});
339+
});
340+
}
272341
})
273342
274343
onBeforeUnmount(() => {

dashboard/src/components/VideoCard.vue

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<template>
22
<div
33
class="video-card"
4+
:class="{ 'last-clicked': isLastClicked }"
45
@click="handleCardClick"
56
>
67
<div class="card-poster">
@@ -71,6 +72,7 @@ import {
7172
IconHeartFill,
7273
IconDelete
7374
} from '@arco-design/web-vue/es/icon'
75+
import { useVisitedStore } from '@/stores/visitedStore'
7476
7577
const props = defineProps({
7678
item: {
@@ -86,6 +88,9 @@ const props = defineProps({
8688
8789
const emit = defineEmits(['card-click', 'image-click', 'action-click'])
8890
91+
// 访问状态管理
92+
const visitedStore = useVisitedStore()
93+
8994
// 计算属性
9095
const showHistoryInfo = computed(() => props.type === 'history')
9196
@@ -122,6 +127,12 @@ const cardTitle = computed(() => {
122127
return props.type === 'video' ? props.item.vod_name : props.item.name
123128
})
124129
130+
// 检查是否是最后点击的视频
131+
const isLastClicked = computed(() => {
132+
const videoId = props.type === 'video' ? props.item.vod_id : props.item.id
133+
return visitedStore.isLastClicked(videoId)
134+
})
135+
125136
// 事件处理
126137
const handleCardClick = () => {
127138
emit('card-click', props.item)
@@ -136,7 +147,8 @@ const handleActionClick = () => {
136147
}
137148
138149
const handleImageError = (event) => {
139-
event.target.src = '/default-poster.svg'
150+
// 使用相对路径,适配子目录部署
151+
event.target.src = './default-poster.svg'
140152
event.target.style.objectFit = 'contain'
141153
event.target.style.backgroundColor = '#f7f8fa'
142154
}
@@ -167,6 +179,11 @@ const formatDate = (dateString) => {
167179
border-color: var(--color-primary-light-3);
168180
}
169181
182+
/* 最后点击的视频样式 */
183+
.video-card.last-clicked .card-title {
184+
color: var(--color-primary-6);
185+
}
186+
170187
.card-poster {
171188
position: relative;
172189
width: 100%;
@@ -292,4 +309,9 @@ const formatDate = (dateString) => {
292309
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
293310
backdrop-filter: blur(4px);
294311
}
312+
313+
/* 最后点击的视频样式 */
314+
.video-card.last-clicked .card-title {
315+
color: var(--color-primary);
316+
}
295317
</style>

dashboard/src/components/VideoGrid.vue

Lines changed: 75 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
<script setup>
5656
import { onMounted, nextTick, ref, onBeforeUnmount, watch } from 'vue';
5757
import { useRouter } from 'vue-router';
58+
import { useVisitedStore } from '@/stores/visitedStore';
5859
5960
const props = defineProps({
6061
videos: {
@@ -68,33 +69,57 @@ const props = defineProps({
6869
hasMore: {
6970
type: Boolean,
7071
default: false
72+
},
73+
statsText: {
74+
type: String,
75+
default: ''
76+
},
77+
showStats: {
78+
type: Boolean,
79+
default: false
80+
},
81+
// 新增:来源页面信息
82+
sourceRoute: {
83+
type: Object,
84+
default: () => ({})
7185
}
7286
});
7387
7488
const emit = defineEmits(['load-more', 'scroll-bottom']);
7589
7690
const router = useRouter();
91+
const visitedStore = useVisitedStore();
7792
const containerRef = ref(null);
7893
const scrollbarRef = ref(null);
7994
const scrollAreaHeight = ref(0);
8095
96+
8197
// 视频点击处理
8298
const handleVideoClick = (video) => {
8399
if (video && video.vod_id) {
100+
// 记录最后点击的视频
101+
visitedStore.setLastClicked(video.vod_id, video.vod_name)
102+
103+
const routeQuery = {
104+
name: video.vod_name,
105+
pic: video.vod_pic,
106+
year: video.vod_year,
107+
area: video.vod_area,
108+
type: video.vod_type,
109+
remarks: video.vod_remarks,
110+
content: video.vod_content,
111+
actor: video.vod_actor,
112+
director: video.vod_director,
113+
// 添加来源页面信息
114+
sourceRouteName: props.sourceRoute?.name || '',
115+
sourceRouteParams: JSON.stringify(props.sourceRoute?.params || {}),
116+
sourceRouteQuery: JSON.stringify(props.sourceRoute?.query || {})
117+
}
118+
84119
router.push({
85120
name: 'VideoDetail',
86121
params: { id: video.vod_id },
87-
query: {
88-
name: video.vod_name,
89-
pic: video.vod_pic,
90-
year: video.vod_year,
91-
area: video.vod_area,
92-
type: video.vod_type,
93-
remarks: video.vod_remarks,
94-
content: video.vod_content,
95-
actor: video.vod_actor,
96-
director: video.vod_director
97-
}
122+
query: routeQuery
98123
});
99124
}
100125
};
@@ -116,7 +141,14 @@ const updateScrollAreaHeight = () => {
116141
containerHeight = Math.max(window.innerHeight - 120, 500);
117142
}
118143
119-
const newHeight = Math.max(containerHeight - footerHeight, 400); // 移除硬编码的32px减值,让scrollbar占满容器
144+
// 根据视频内容动态调整高度减值
145+
// 如果没有视频或视频很少,减去100px强制触发滚动条
146+
// 如果有足够视频内容,只减去少量padding空间
147+
const hasEnoughContent = props.videos && props.videos.length >= 17;
148+
const heightReduction = hasEnoughContent ? 4 : 100;
149+
150+
const newHeight = Math.max(containerHeight - footerHeight - heightReduction, 400);
151+
console.log(`视频数量: ${props.videos?.length || 0}, 内容充足: ${hasEnoughContent}, 高度减值: ${heightReduction}, 最终高度: ${newHeight}`);
120152
scrollAreaHeight.value = newHeight;
121153
}, 100); // 增加延迟确保DOM完全渲染
122154
});
@@ -175,9 +207,38 @@ watch(() => [props.videos, props.showStats], () => {
175207
checkTextOverflow();
176208
});
177209
210+
// 滚动位置恢复方法
211+
const restoreScrollPosition = (scrollPosition) => {
212+
if (scrollPosition && scrollbarRef.value) {
213+
// 使用requestAnimationFrame确保DOM已渲染
214+
requestAnimationFrame(() => {
215+
const scrollContainer = scrollbarRef.value?.$el?.querySelector('.arco-scrollbar-container');
216+
if (scrollContainer) {
217+
// 使用平滑滚动
218+
scrollContainer.scrollTo({
219+
top: scrollPosition,
220+
behavior: 'smooth'
221+
});
222+
console.log('VideoGrid恢复滚动位置:', scrollPosition);
223+
}
224+
});
225+
}
226+
};
227+
228+
// 获取当前滚动位置
229+
const getCurrentScrollPosition = () => {
230+
if (scrollbarRef.value) {
231+
const scrollContainer = scrollbarRef.value?.$el?.querySelector('.arco-scrollbar-container');
232+
return scrollContainer?.scrollTop || 0;
233+
}
234+
return 0;
235+
};
236+
178237
// 暴露方法给父组件
179238
defineExpose({
180-
checkTextOverflow
239+
checkTextOverflow,
240+
restoreScrollPosition,
241+
getCurrentScrollPosition
181242
});
182243
</script>
183244
@@ -197,7 +258,7 @@ defineExpose({
197258
.video-scroll-container {
198259
width: 100%;
199260
flex: 1; /* 使用flex让scrollbar占满剩余空间 */
200-
padding: 16px 20px 8px 16px; /* 上右下左:减少下padding */
261+
padding: 2px 20px 2px 16px; /* 大幅减少上下padding,让scrollbar占用更多空间 */
201262
}
202263
203264
.video_list_hover {

0 commit comments

Comments
 (0)