Skip to content

Commit d4afe73

Browse files
committed
Update:拆组件半成品
1 parent 73dcbb3 commit d4afe73

File tree

4 files changed

+370
-6
lines changed

4 files changed

+370
-6
lines changed

dashboard/src/components/Layout.vue

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,13 @@ export default defineComponent({
104104
menuItems: [
105105
{id: 1, name: '主页', icon: 'icon-shouye', route: '/'},
106106
{id: 2, name: '点播', icon: 'icon-dianbo', route: '/video'},
107-
{id: 3, name: '直播', icon: 'icon-dianshizhibo', route: '/live'},
108-
{id: 4, name: '书画柜', icon: 'icon-2zushushishujia', route: '/reader'},
109-
{id: 5, name: '解析', icon: 'icon-yumingjiexi', route: '/parser'},
110-
{id: 6, name: '收藏', icon: 'icon-shoucang', route: '/collection'},
111-
{id: 7, name: '历史', icon: 'icon-lishi', route: '/history'},
112-
{id: 8, name: '设置', icon: 'icon-shezhi', route: '/settings'}
107+
{id: 3, name: '点播2', icon: 'icon-dianbo', route: '/video2'},
108+
{id: 4, name: '直播', icon: 'icon-dianshizhibo', route: '/live'},
109+
{id: 5, name: '书画柜', icon: 'icon-2zushushishujia', route: '/reader'},
110+
{id: 6, name: '解析', icon: 'icon-yumingjiexi', route: '/parser'},
111+
{id: 7, name: '收藏', icon: 'icon-shoucang', route: '/collection'},
112+
{id: 8, name: '历史', icon: 'icon-lishi', route: '/history'},
113+
{id: 9, name: '设置', icon: 'icon-shezhi', route: '/settings'}
113114
],
114115
logoSrc: logo,
115116
logoDesc:'the logo for this application',
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<template>
2+
<a-modal
3+
:visible="visible"
4+
:title="title"
5+
:width="dialogWidth"
6+
class="change_rule_dialog"
7+
append-to-body
8+
>
9+
<a-input
10+
v-model="siteFilter"
11+
placeholder="请输入站源名称"
12+
class="site_filter_input"
13+
allow-clear
14+
/>
15+
16+
<a-form
17+
:model="form"
18+
label-width="120px"
19+
class="change_rule_form"
20+
>
21+
<div class="button-container">
22+
<div
23+
v-for="(site, index) in filteredSites"
24+
:key="index"
25+
class="btn-item"
26+
>
27+
<a-button
28+
type="primary"
29+
:status="form.new_site.key === site.key ? 'success' : 'primary'"
30+
size="medium"
31+
@click="handleChangeRule(site)"
32+
>
33+
{{ site.name }}
34+
</a-button>
35+
</div>
36+
</div>
37+
</a-form>
38+
39+
<template #footer>
40+
<div class="dialog-footer-right dialog-footer">
41+
<a-button type="primary" status="danger" @click="handleConfirmClear">清除缓存</a-button>
42+
<a-button type="primary" @click="handleConfirmChange">确认换源</a-button>
43+
</div>
44+
</template>
45+
</a-modal>
46+
</template>
47+
48+
<script setup>
49+
import { ref, computed, nextTick } from 'vue';
50+
51+
const props = defineProps({
52+
visible: Boolean,
53+
title: String,
54+
sites: Array,
55+
currentSiteKey: String,
56+
});
57+
const emit = defineEmits(['update:visible', 'confirm-clear', 'confirm-change', 'change-rule']);
58+
59+
const siteFilter = ref('');
60+
const form = ref({ new_site: {} });
61+
62+
const filteredSites = computed(() => {
63+
const inputLower = siteFilter.value.toLowerCase();
64+
return props.sites.filter(site => site.name.toLowerCase().includes(inputLower));
65+
});
66+
67+
const dialogWidth = computed(() => (window.innerWidth < 768 ? '100%' : '600px'));
68+
69+
const handleChangeRule = (site) => {
70+
form.value.new_site = site;
71+
emit('change-rule', site);
72+
};
73+
74+
const handleConfirmClear = () => {
75+
emit('confirm-clear');
76+
emit('update:visible', false);
77+
};
78+
79+
const handleConfirmChange = () => {
80+
emit('confirm-change', form.value.new_site);
81+
emit('update:visible', false);
82+
};
83+
</script>
84+
85+
<style>
86+
.change_rule_dialog .arco-modal-body {
87+
padding: 1px !important; /* 使用 !important 强制覆盖 */
88+
}
89+
</style>
90+
91+
92+
<style scoped>
93+
94+
.change_rule_form {
95+
min-height: 200px;
96+
max-height: 400px;
97+
}
98+
99+
.site_filter_input {
100+
padding: 5px 5px 5px 5px;
101+
border-radius: 12px;
102+
width: calc(31.3% * 3);
103+
}
104+
105+
.dialog-footer button {
106+
margin-right: 20px;
107+
}
108+
109+
.dialog-footer-left {
110+
display: flex;
111+
justify-content: flex-start; /* 将按钮对齐到左侧 */
112+
}
113+
114+
.dialog-footer-right {
115+
display: flex;
116+
justify-content: flex-end; /* 将按钮对齐到右侧 */
117+
}
118+
119+
.custom-confirm {
120+
max-width: 90%; /* 最大宽度为 90% */
121+
width: auto; /* 宽度自适应内容 */
122+
}
123+
124+
.button-container {
125+
width: 100%;
126+
max-height: 400px;
127+
overflow-y: scroll;
128+
display: flex;
129+
flex-wrap: wrap;
130+
}
131+
.btn-item {
132+
text-align: center;
133+
width: calc(31.3%);
134+
padding: 2px;
135+
}
136+
</style>

dashboard/src/router/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {createRouter, createWebHistory} from 'vue-router';
22
import Home from '@/views/Home.vue';
33
import Video from '@/views/Video.vue';
4+
import Video2 from '@/views/Video2.vue';
45
import Live from '@/views/Live.vue';
56
import Settings from '@/views/Settings.vue';
67
import Collection from '@/views/Collection.vue';
@@ -11,6 +12,7 @@ import Parser from '@/views/Parser.vue';
1112
const routes = [
1213
{path: '/', component: Home},
1314
{path: '/video', component: Video},
15+
{path: '/video2', component: Video2},
1416
{path: '/live', component: Live},
1517
{path: '/settings', component: Settings},
1618
{path: '/collection', component: Collection},

dashboard/src/views/Video2.vue

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
<template>
2+
<!-- 内容上方面包屑-->
3+
<a-breadcrumb :style="{ margin: '16px 0' }">
4+
<a-breadcrumb-item>Video</a-breadcrumb-item>
5+
6+
<div class="header-left">
7+
<a-button type="outline" status="success" shape="round" @click="handleOpenForm">
8+
<template #icon>
9+
<icon-apps/>
10+
</template>
11+
<template #default>{{ form.now_site_title }}</template>
12+
</a-button>
13+
14+
<a-button type="outline" status="success" shape="round" @click="refreshPage">
15+
<template #icon>
16+
<icon-refresh/>
17+
</template>
18+
<template #default>重载源</template>
19+
</a-button>
20+
</div>
21+
22+
<!-- 中间搜索框 -->
23+
<div class="header-center">
24+
<a-input-search
25+
placeholder="搜索视频"
26+
enter-button
27+
@search="onSearch"
28+
style="width: 300px;"
29+
/>
30+
</div>
31+
32+
<!-- 右侧控制按钮 -->
33+
<div class="header-right">
34+
<a-button type="outline" status="success" shape="round" @click="minimize">
35+
<template #icon>
36+
<icon-bug/>
37+
</template>
38+
<template #default>调试</template>
39+
</a-button>
40+
41+
<a-button type="outline" status="success" shape="round" @click="maximize">
42+
<template #icon>
43+
<icon-settings/>
44+
</template>
45+
<template #default>设置</template>
46+
</a-button>
47+
<a-button type="outline" status="success" shape="round" @click="closeWindow">
48+
<template #icon>
49+
<icon-user/>
50+
</template>
51+
<template #default>用户设置</template>
52+
</a-button>
53+
54+
<!-- 当前时间显示 -->
55+
<div class="current-time">
56+
<span>{{ currentDateTime }}</span>
57+
</div>
58+
</div>
59+
</a-breadcrumb>
60+
61+
<!-- 内容区域 -->
62+
<a-layout-content class="content">
63+
<div>
64+
<h1>点播</h1>
65+
<p>这是点播页面的内容。</p>
66+
<ul v-if="form.sites.length > 0">
67+
<li v-for="site in form.sites" :key="site.key">{{ site.name }}</li>
68+
</ul>
69+
<p v-else>没有站点信息。</p>
70+
</div>
71+
</a-layout-content>
72+
73+
<SourceDialog
74+
:visible="form.visible"
75+
:title="form.form_title"
76+
:sites="form.sites"
77+
:currentSiteKey="form.now_site.key"
78+
@update:visible="val => form.visible = val"
79+
@confirm-clear="handleConfirmClear"
80+
@confirm-change="handleConfirmChange"
81+
@change-rule="handleChangeRule"
82+
/>
83+
</template>
84+
85+
<script setup>
86+
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue';
87+
import SourceDialog from '../components/SourceDialog.vue';
88+
import req from '@/utils/req';
89+
import { useSiteStore } from '@/stores/siteStore';
90+
91+
const { nowSite, setCurrentSite } = useSiteStore();
92+
93+
const currentDateTime = ref('');
94+
const form = reactive({
95+
sites: [],
96+
now_site_title: 'hipy影视',
97+
now_site: {},
98+
visible: false,
99+
form_title: '',
100+
});
101+
const timer = ref(null);
102+
const getData = async () => {
103+
try {
104+
let response;
105+
if(req.defaults.baseURL === ''){
106+
response = await req.get('/mock/data.json');
107+
response = response.config;
108+
}else{
109+
response = await req.get('/config'); // 假设这个请求返回 sites 数组
110+
}
111+
form.sites = response.sites; // 给 form.sites 赋值
112+
} catch (error) {
113+
console.error('请求数据失败:', error);
114+
}
115+
};
116+
117+
const getNowSite = () => {
118+
if (nowSite && nowSite.name) {
119+
form.now_site = nowSite;
120+
form.now_site_title = nowSite.name;
121+
}
122+
}
123+
124+
const checkNowSite = () => {
125+
form.new_site = form.now_site
126+
if (!form.new_site.key && form.sites.length > 0) {
127+
form.new_site = form.sites[0]
128+
} else if (form.new_site.key && !form.sites.map(i => i.key).includes(form.new_site.key)) {
129+
form.new_site = form.sites[0]
130+
}
131+
}
132+
133+
const formatDate = (date) => {
134+
const options = {
135+
weekday: 'long', // 星期几
136+
year: 'numeric',
137+
month: 'numeric',
138+
day: 'numeric',
139+
hour: '2-digit',
140+
minute: '2-digit',
141+
second: '2-digit',
142+
hour12: true, // 12小时制
143+
};
144+
return date.toLocaleString('zh-CN', options);
145+
};
146+
147+
// 启动定时器
148+
const startClock = () => {
149+
timer.value = setInterval(() => {
150+
currentDateTime.value = formatDate(new Date());
151+
}, 1000); // 每秒更新时间
152+
};
153+
154+
const refreshPage = () => {
155+
window.location.reload();
156+
};
157+
158+
const minimize = () => {};
159+
const maximize = () => {};
160+
const closeWindow = () => {};
161+
const onSearch = (value) => console.log('搜索内容:', value);
162+
163+
const handleChangeRule = (site) => form.new_site = site;
164+
165+
const handleConfirmClear = () => {
166+
form.now_site = form.new_site;
167+
setCurrentSite(form.now_site);
168+
form.visible = false;
169+
getData();
170+
checkNowSite();
171+
};
172+
173+
const handleConfirmChange = (site) => {
174+
console.log('确认换源');
175+
form.now_site = site;
176+
setCurrentSite(site);
177+
form.now_site_title = site.name;
178+
form.visible = false;
179+
};
180+
181+
const handleOpenForm = () => {
182+
form.visible = true;
183+
form.form_title = `请选择数据源(${form.sites.length})`;
184+
checkNowSite();
185+
};
186+
187+
// 页面加载时获取数据
188+
onMounted(() => {
189+
getData(); // 页面加载时获取数据
190+
getNowSite(); // 获取储存的当前源
191+
startClock(); // 启动时钟
192+
});
193+
194+
195+
// 清理定时器
196+
onBeforeUnmount(() => {
197+
if (timer.value) {
198+
clearInterval(timer.value); // 销毁时清除定时器
199+
}
200+
});
201+
</script>
202+
203+
<style scoped>
204+
/* 样式代码 */
205+
.header-left,
206+
.header-right {
207+
display: flex;
208+
align-items: center;
209+
}
210+
211+
.header-left button,
212+
.header-right button {
213+
margin-right: 10px;
214+
}
215+
216+
.header-center {
217+
flex-grow: 1;
218+
display: flex;
219+
justify-content: center;
220+
}
221+
222+
.header-center a-input-search {
223+
width: 300px;
224+
}
225+
</style>

0 commit comments

Comments
 (0)