Skip to content

Commit 5496976

Browse files
author
Taois
committed
feat:目录模式
1 parent 8176fe3 commit 5496976

File tree

7 files changed

+783
-41
lines changed

7 files changed

+783
-41
lines changed

dashboard/src/api/modules/module.js

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import { get, post } from '../request'
77
import { API_PATHS, MODULE_ACTIONS, PAGINATION } from '../config'
8+
import { processExtendParam } from '@/utils/apiUtils'
89
import axios from 'axios'
910

1011
/**
@@ -44,29 +45,7 @@ const parseHeaders = (headers) => {
4445
return {}
4546
}
4647

47-
/**
48-
* 处理extend参数,确保对象类型转换为JSON字符串
49-
* @param {string|object} extend - 扩展参数
50-
* @returns {string|undefined} 处理后的extend参数
51-
*/
52-
const processExtendParam = (extend) => {
53-
if (!extend) {
54-
return undefined
55-
}
56-
57-
// 如果extend是对象类型,转换为JSON字符串
58-
if (typeof extend === 'object' && extend !== null) {
59-
try {
60-
return JSON.stringify(extend)
61-
} catch (error) {
62-
console.warn('extend参数JSON序列化失败:', error)
63-
return undefined
64-
}
65-
}
66-
67-
// 如果已经是字符串,直接返回
68-
return extend
69-
}
48+
7049

7150
/**
7251
* 构建模块接口URL

dashboard/src/api/services/video.js

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
} from '../modules/module'
1616
import { parseVideo } from '../modules/parse'
1717
import { encodeFilters, validateModule, validateVideoId } from '../utils'
18+
import { processExtendParam } from '@/utils/apiUtils'
1819
import {
1920
createVideoInfo,
2021
createSearchParams,
@@ -23,6 +24,8 @@ import {
2324
SORT_TYPES
2425
} from '../types'
2526

27+
28+
2629
/**
2730
* 视频服务类
2831
*/
@@ -112,8 +115,9 @@ class VideoService {
112115
}
113116

114117
// 添加extend参数
115-
if (extend) {
116-
requestParams.extend = extend
118+
const processedExtend = processExtendParam(extend)
119+
if (processedExtend) {
120+
requestParams.extend = processedExtend
117121
}
118122

119123
// 添加apiUrl参数
@@ -175,8 +179,9 @@ class VideoService {
175179
if (apiUrl) {
176180
params.apiUrl = apiUrl
177181
}
178-
if (extend) {
179-
params.extend = extend
182+
const processedExtend = processExtendParam(extend)
183+
if (processedExtend) {
184+
params.extend = processedExtend
180185
}
181186
const response = await getVideoDetail(module, params)
182187

@@ -227,8 +232,9 @@ class VideoService {
227232
}
228233

229234
// 添加extend参数
230-
if (extend) {
231-
requestParams.extend = extend
235+
const processedExtend = processExtendParam(extend)
236+
if (processedExtend) {
237+
requestParams.extend = processedExtend
232238
}
233239

234240
// 添加apiUrl参数
@@ -276,8 +282,9 @@ class VideoService {
276282
if (apiUrl) {
277283
params.apiUrl = apiUrl
278284
}
279-
if (extend) {
280-
params.extend = extend
285+
const processedExtend = processExtendParam(extend)
286+
if (processedExtend) {
287+
params.extend = processedExtend
281288
}
282289
const response = await getPlayData(module, params)
283290

@@ -348,7 +355,7 @@ class VideoService {
348355
try {
349356
console.log('VideoService: 开始解析选集播放地址', { module, params })
350357

351-
const parseParams = { play, extend }
358+
const parseParams = { play, extend: processExtendParam(extend) }
352359

353360
// 添加flag参数(线路名称)
354361
if (flag) {
@@ -392,7 +399,7 @@ class VideoService {
392399
const actionData = {
393400
action: actionName.trim(),
394401
value: options.value || '',
395-
extend: options.extend,
402+
extend: processExtendParam(options.extend),
396403
apiUrl: options.apiUrl
397404
}
398405

@@ -424,7 +431,8 @@ class VideoService {
424431
// 清除相关缓存
425432
this.clearModuleCache(module)
426433

427-
const response = await refreshModule(module, extend, apiUrl)
434+
const processedExtend = processExtendParam(extend)
435+
const response = await refreshModule(module, processedExtend, apiUrl)
428436

429437
return {
430438
success: true,
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
<template>
2+
<div class="folder-breadcrumb" v-if="breadcrumbs.length > 0">
3+
<div class="breadcrumb-container">
4+
<a-breadcrumb separator=">">
5+
<a-breadcrumb-item
6+
v-for="(item, index) in breadcrumbs"
7+
:key="item.vod_id"
8+
class="breadcrumb-item"
9+
:class="{ 'is-current': index === breadcrumbs.length - 1 }"
10+
>
11+
<span
12+
v-if="index === breadcrumbs.length - 1"
13+
class="current-item"
14+
>
15+
{{ item.vod_name }}
16+
</span>
17+
<a
18+
v-else
19+
@click="handleBreadcrumbClick(item, index)"
20+
class="breadcrumb-link"
21+
>
22+
{{ item.vod_name }}
23+
</a>
24+
</a-breadcrumb-item>
25+
</a-breadcrumb>
26+
</div>
27+
28+
<!-- 操作按钮 -->
29+
<div class="breadcrumb-actions">
30+
<a-button
31+
size="small"
32+
type="text"
33+
@click="handleGoBack"
34+
:disabled="breadcrumbs.length <= 1"
35+
class="action-btn"
36+
>
37+
<template #icon>
38+
<icon-left />
39+
</template>
40+
返回上级
41+
</a-button>
42+
43+
<a-button
44+
size="small"
45+
type="text"
46+
@click="handleGoHome"
47+
:disabled="breadcrumbs.length <= 1"
48+
class="action-btn"
49+
>
50+
<template #icon>
51+
<icon-home />
52+
</template>
53+
返回根目录
54+
</a-button>
55+
56+
<a-button
57+
size="small"
58+
type="primary"
59+
@click="handleExitFolder"
60+
class="action-btn exit-btn"
61+
>
62+
<template #icon>
63+
<icon-close />
64+
</template>
65+
退出目录模式
66+
</a-button>
67+
</div>
68+
</div>
69+
</template>
70+
71+
<script setup>
72+
import { computed } from 'vue';
73+
import { IconLeft, IconHome, IconClose } from '@arco-design/web-vue/es/icon';
74+
75+
const props = defineProps({
76+
breadcrumbs: {
77+
type: Array,
78+
default: () => []
79+
}
80+
});
81+
82+
const emit = defineEmits(['navigate', 'go-back', 'go-home', 'exit-folder']);
83+
84+
// 处理面包屑点击
85+
const handleBreadcrumbClick = (item, index) => {
86+
console.log('🗂️ [DEBUG] 面包屑点击:', item, index);
87+
emit('navigate', item, index);
88+
};
89+
90+
// 返回上级
91+
const handleGoBack = () => {
92+
if (props.breadcrumbs.length > 1) {
93+
const parentIndex = props.breadcrumbs.length - 2;
94+
const parentItem = props.breadcrumbs[parentIndex];
95+
console.log('🗂️ [DEBUG] 返回上级:', parentItem);
96+
emit('go-back', parentItem, parentIndex);
97+
}
98+
};
99+
100+
// 返回根目录
101+
const handleGoHome = () => {
102+
if (props.breadcrumbs.length > 1) {
103+
const rootItem = props.breadcrumbs[0];
104+
console.log('🗂️ [DEBUG] 返回根目录:', rootItem);
105+
emit('go-home', rootItem, 0);
106+
}
107+
};
108+
109+
// 退出Folder模式
110+
const handleExitFolder = () => {
111+
console.log('🗂️ [DEBUG] 退出Folder模式');
112+
emit('exit-folder');
113+
};
114+
</script>
115+
116+
<style scoped>
117+
.folder-breadcrumb {
118+
background: #f8f9fa;
119+
border: 1px solid #e5e7eb;
120+
border-radius: 8px;
121+
padding: 12px 16px;
122+
margin-bottom: 16px;
123+
display: flex;
124+
align-items: center;
125+
justify-content: space-between;
126+
gap: 16px;
127+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
128+
}
129+
130+
.breadcrumb-container {
131+
flex: 1;
132+
min-width: 0;
133+
}
134+
135+
.breadcrumb-item {
136+
font-size: 14px;
137+
}
138+
139+
.breadcrumb-link {
140+
color: #1890ff;
141+
text-decoration: none;
142+
cursor: pointer;
143+
transition: color 0.2s ease;
144+
padding: 4px 8px;
145+
border-radius: 4px;
146+
display: inline-block;
147+
}
148+
149+
.breadcrumb-link:hover {
150+
color: #40a9ff;
151+
background-color: rgba(24, 144, 255, 0.06);
152+
}
153+
154+
.current-item {
155+
color: #262626;
156+
font-weight: 500;
157+
padding: 4px 8px;
158+
background-color: rgba(24, 144, 255, 0.1);
159+
border-radius: 4px;
160+
display: inline-block;
161+
}
162+
163+
.breadcrumb-actions {
164+
display: flex;
165+
gap: 8px;
166+
flex-shrink: 0;
167+
}
168+
169+
.action-btn {
170+
color: #6b7280;
171+
border: 1px solid #d1d5db;
172+
background: white;
173+
transition: all 0.2s ease;
174+
}
175+
176+
.action-btn:hover:not(:disabled) {
177+
color: #1890ff;
178+
border-color: #1890ff;
179+
background: rgba(24, 144, 255, 0.04);
180+
}
181+
182+
.action-btn:disabled {
183+
opacity: 0.5;
184+
cursor: not-allowed;
185+
}
186+
187+
.exit-btn {
188+
background: #ff4d4f !important;
189+
border-color: #ff4d4f !important;
190+
color: white !important;
191+
}
192+
193+
.exit-btn:hover:not(:disabled) {
194+
background: #ff7875 !important;
195+
border-color: #ff7875 !important;
196+
color: white !important;
197+
}
198+
199+
/* 响应式设计 */
200+
@media (max-width: 768px) {
201+
.folder-breadcrumb {
202+
flex-direction: column;
203+
align-items: stretch;
204+
gap: 12px;
205+
}
206+
207+
.breadcrumb-actions {
208+
justify-content: center;
209+
}
210+
211+
.action-btn {
212+
flex: 1;
213+
max-width: 120px;
214+
}
215+
}
216+
217+
/* 面包屑溢出处理 */
218+
.breadcrumb-container :deep(.arco-breadcrumb) {
219+
overflow: hidden;
220+
}
221+
222+
.breadcrumb-container :deep(.arco-breadcrumb-item) {
223+
max-width: 200px;
224+
overflow: hidden;
225+
}
226+
227+
.breadcrumb-container :deep(.arco-breadcrumb-item) .breadcrumb-link,
228+
.breadcrumb-container :deep(.arco-breadcrumb-item) .current-item {
229+
overflow: hidden;
230+
text-overflow: ellipsis;
231+
white-space: nowrap;
232+
max-width: 100%;
233+
}
234+
</style>

dashboard/src/components/VideoGrid.vue

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ const props = defineProps({
114114
}
115115
});
116116
117-
const emit = defineEmits(['load-more', 'scroll-bottom', 'refresh-list', 'special-action']);
117+
const emit = defineEmits(['load-more', 'scroll-bottom', 'refresh-list', 'special-action', 'folder-navigate']);
118118
119119
const router = useRouter();
120120
const visitedStore = useVisitedStore();
@@ -131,6 +131,18 @@ const currentActionData = ref(null);
131131
// 视频点击处理
132132
const handleVideoClick = async (video) => {
133133
if (video && video.vod_id) {
134+
// 检查是否为folder类型
135+
if (video.vod_tag && video.vod_tag.includes('folder')) {
136+
console.log('VideoGrid检测到folder类型:', video);
137+
// 触发folder导航事件,传递当前点击的视频信息
138+
emit('folder-navigate', {
139+
vod_id: video.vod_id,
140+
vod_name: video.vod_name,
141+
vod_tag: video.vod_tag
142+
});
143+
return;
144+
}
145+
134146
// 检查是否为action类型
135147
if (video.vod_tag === 'action') {
136148
try {

0 commit comments

Comments
 (0)