DESKTOP-FUDKNA8\znjsz 6 місяці тому
джерело
коміт
d77506ed31
4 змінених файлів з 373 додано та 172 видалено
  1. +68
    -37
      src/MainPage.vue
  2. +289
    -134
      src/components/SettingDialog.vue
  3. +1
    -1
      src/main.js
  4. +15
    -0
      src/store/settings.js

+ 68
- 37
src/MainPage.vue Переглянути файл

@@ -13,7 +13,7 @@ import { useSettings } from "./store/settings";

const props = defineProps(["path"]);

const pages = ['3d', 'data', 'realtime', 'alert', 'announcement']
const pages = ["3d", "data", "realtime", "alert", "announcement"];
const currentPage = ref("3d");
const handlePageChange = (page) => {
currentPage.value = page;
@@ -23,67 +23,84 @@ const mainContainer = ref(null);
const store = useSettings();
const timer = ref(null);

function startCarousel(pages, duration) {
if (timer.value) clearInterval(timer.value);
timer.value = setInterval(() => {
handlePageChange(
pages[(pages.indexOf(currentPage.value) + 1) % pages.length]
);
}, duration);
}

store.$subscribe((mutation, state) => {
const pages = state.settings.carouselPages;
// 如果更新了时间
if (mutation.events.key == 'carouselTime' && state.settings.carouselTime > 0 && state.settings.carousel) {
if (timer.value) clearInterval(timer.value);
timer.value = setInterval(() => {
handlePageChange(pages[(pages.indexOf(currentPage.value) + 1) % pages.length])
}, state.settings.carouselTime * 1000);
} else if (mutation.events.key == 'carousel') {
if (
mutation.events.key == "carouselTime" &&
state.settings.carouselTime > 0 &&
state.settings.carousel
) {
startCarousel(pages, state.settings.carouselTime * 1000);
} else if (mutation.events.key == "carousel") {
// 如果更新了状态
if (state.settings.carousel) {
timer.value = setInterval(() => {
handlePageChange(pages[(pages.indexOf(currentPage.value) + 1) % pages.length])
}, state.settings.carouselTime * 1000);
startCarousel(pages, state.settings.carouselTime * 1000);
} else {
clearInterval(timer.value);
timer.value = null;
}
} else if (mutation.events.key == "carouselPages") {
if (state.settings.carousel) {
startCarousel(pages, state.settings.carouselTime * 1000);
} else {
clearInterval(timer.value);
timer.value = null;
}
}
})

});

// 检查状态
onMounted(() => {
const settings = store.settings;
const pages = settings.carouselPages;
if (settings.carousel) {
// 开始轮播
if (timer.value) clearInterval(timer.value);
timer.value = setInterval(() => {
handlePageChange(pages[(pages.indexOf(currentPage.value) + 1) % pages.length])
handlePageChange(
pages[(pages.indexOf(currentPage.value) + 1) % pages.length]
);
}, settings.carouselTime * 1000);
}
// 设置分辨率
handleResolutionChange(settings.resolution.width, settings.resolution.height);
})

});

const pathMap = {
// 钢三线
'/3-1': 1,
'/3-2': 2,
'/3-3': 11, // 3,
'/3-4': 12,
"/3-1": 1,
"/3-2": 2,
"/3-3": 11, // 3,
"/3-4": 12,
// 钢二线
'/2-1': 5,
'/2-2': 6,
'/2-3': 7,
'/2-4': 4,
"/2-1": 5,
"/2-2": 6,
"/2-3": 7,
"/2-4": 4,
// 钢一线
'/1-1': 9,
'/1-2': 10,
'/1-3': 3,
'/1-4': 8
}
"/1-1": 9,
"/1-2": 10,
"/1-3": 3,
"/1-4": 8,
};

function handleResolutionChange(width, height) {
console.log('document.documentElement', document.documentElement)
console.log("document.documentElement", document.documentElement);
if (mainContainer.value) {
// mainContainer.value.style.width = `${width}px`;
// mainContainer.value.style.height = `${height}px`;
// changeScale(mainContainer.value, width, height)
changeScale(mainContainer.value, width, height)
changeScale(mainContainer.value, width, height);
}
}

@@ -102,23 +119,37 @@ function resetScale(elm) {
elm.style.transform = "initial";
elm.style.transformOrigin = "initial";
}

</script>

<template>
<div id="main-container" ref="mainContainer" class="main-container">
<DatetimeTool v-if="currentPage !== 'announcement'" />
<Tools v-if="currentPage !== 'announcement'" @change-resolution="handleResolutionChange" />
<Tools
v-if="currentPage !== 'announcement'"
@change-resolution="handleResolutionChange"
/>
<AppHeader v-if="currentPage !== 'announcement'" />
<AnnoucementPage v-if="currentPage === 'announcement'" class="annoucement-page"
@home="() => handlePageChange('3d')" />
<AnnoucementPage
v-if="currentPage === 'announcement'"
class="annoucement-page"
@home="() => handlePageChange('3d')"
/>
<div v-else class="pages-wrapper">
<NavMenu @change="handlePageChange" :value="currentPage" />
<!-- <TriplePage v-if="currentPage === '3d'" :line="pathMap[path] ?? '1'" /> -->
<ThreeDimension v-if="currentPage === '3d'" :line="pathMap[path] ?? '1'" />
<ThreeDimension
v-if="currentPage === '3d'"
:line="pathMap[path] ?? '1'"
/>
<DataPage v-if="currentPage === 'data'" :line="pathMap[path] ?? '1'" />
<AlertListPage v-if="currentPage === 'alert'" :line="pathMap[path] ?? '1'" />
<RealtimePage v-if="currentPage === 'realtime'" :line="pathMap[path] ?? '1'" />
<AlertListPage
v-if="currentPage === 'alert'"
:line="pathMap[path] ?? '1'"
/>
<RealtimePage
v-if="currentPage === 'realtime'"
:line="pathMap[path] ?? '1'"
/>
</div>
</div>
</template>


+ 289
- 134
src/components/SettingDialog.vue Переглянути файл

@@ -1,208 +1,363 @@
<script setup>
import { ref } from 'vue';
import { useSettings } from '../store/settings'
import { ref } from "vue";
import { useSettings } from "../store/settings";
const emit = defineEmits(["close", "change-resolution"]);

const store = useSettings();
const settings = ref(store.settings);
store.$subscribe((mutation, state) => {
settings.value.fullscreen = state.settings.fullscreen;
})
settings.value.fullscreen = state.settings.fullscreen;
});

function handleCancel() {
emit('close')
emit("close");
}

function handleConfirm() {
// alert(JSON.stringify(settings, null, 2))
// changeScale(settings.resolution.width, settings.resolution.height)
if (settings.value.resolution.width < 480) store.settings.resolution.width = 480;
if (settings.value.resolution.width > 7680) store.settings.resolution.width = 7680;
if (settings.value.resolution.height < 270) store.settings.resolution.height = 270;
if (settings.value.resolution.height > 4320) store.settings.resolution.height = 4320;
if (settings.value.resolution.width < 480)
store.settings.resolution.width = 480;
if (settings.value.resolution.width > 7680)
store.settings.resolution.width = 7680;
if (settings.value.resolution.height < 270)
store.settings.resolution.height = 270;
if (settings.value.resolution.height > 4320)
store.settings.resolution.height = 4320;

emit('change-resolution', store.settings.resolution.width, store.settings.resolution.height)
emit(
"change-resolution",
store.settings.resolution.width,
store.settings.resolution.height
);
}
</script>

<template>
<div class="setting-dialog">
<h1>设置</h1>
<div class="main-content">
<div class="form-item">
<label for="carousel">轮播时间</label>
<input id="carousel" type="number" v-model="settings.carouselTime" />
<span>秒</span>
</div>
<div class="form-item">
<label for="resolution1">分辨率</label>
<input id="resolution1" type="number" min="480" max="7680" v-model="settings.resolution.width" />
<span>X</span>
<input id="resolution2" type="number" min="270" max="4320" v-model="settings.resolution.height" />
<span>px</span>
</div>
<div class="form-item selector">
<!-- <div class="opt opt1">
<div class="setting-dialog">
<h1>设置</h1>
<div class="main-content">
<div class="form-item">
<label for="carousel">轮播时间</label>
<input id="carousel" type="number" v-model="settings.carouselTime" />
<span>秒</span>
</div>
<div
class="form-item"
style="display: flex; flex-direction: column; gap: 12px"
>
<label for="carouselPages">轮播项目</label>
<div class="carousel-page__list">
<div>
<input
type="checkbox"
id="cp-3d"
name="carouselPages"
:class="[
settings.carouselPages.includes('3d') ? 'checked' : '',
'carousel-page',
]"
@change="
() => {
store.updateSettings({ type: 'carousel-page', value: '3d' });
}
"
/>
<label for="cp-3d">三维界面</label>
</div>
<div>
<input
type="checkbox"
id="cp-data"
name="carouselPages"
:class="[
settings.carouselPages.includes('data') ? 'checked' : '',
'carousel-page',
]"
@change="
() => {
store.updateSettings({
type: 'carousel-page',
value: 'data',
});
}
"
/>
<label for="cp-data">数据界面</label>
</div>
<div>
<input
type="checkbox"
id="cp-realtime"
name="carouselPages"
:class="[
settings.carouselPages.includes('realtime') ? 'checked' : '',
'carousel-page',
]"
@change="
() => {
store.updateSettings({
type: 'carousel-page',
value: 'realtime',
});
}
"
/>
<label for="cp-realtime">实时数据</label>
</div>
<div>
<input
type="checkbox"
id="cp-alert"
name="carouselPages"
:class="[
settings.carouselPages.includes('alert') ? 'checked' : '',
'carousel-page',
]"
@change="
() => {
store.updateSettings({
type: 'carousel-page',
value: 'alert',
});
}
"
/>
<label for="cp-alert">报警列表</label>
</div>
<div>
<input
type="checkbox"
id="cp-announcement"
name="carouselPages"
:class="[
settings.carouselPages.includes('announcement')
? 'checked'
: '',
'carousel-page',
]"
@change="
() => {
store.updateSettings({
type: 'carousel-page',
value: 'announcement',
});
}
"
/>
<label for="cp-announcement">公告页面</label>
</div>
</div>
</div>
<div class="form-item">
<label for="resolution1">分辨率</label>
<input
id="resolution1"
type="number"
min="480"
max="7680"
v-model="settings.resolution.width"
/>
<span>X</span>
<input
id="resolution2"
type="number"
min="270"
max="4320"
v-model="settings.resolution.height"
/>
<span>px</span>
</div>
<div class="form-item selector">
<!-- <div class="opt opt1">
<input type="checkbox" id="fullscreen" name="fullscreen" :class="[settings.fullscreen ? 'checked' : '']"
v-model="settings.fullscreen" />
<label for="fullscreen">全屏显示</label>
</div> -->
<div class="opt opt2">
<input type="checkbox" id="status" name="status" :class="[settings.eqStatus ? 'checked' : '']"
v-model="settings.eqStatus" />
<label for="status">设备状态</label>
</div>
</div>
</div>
<div class="footer">
<button @click="handleCancel" class="btn btn-cancel">取消</button>
<button @click="handleConfirm" class="btn btn-confirm">确认</button>
<div class="opt opt2">
<input
type="checkbox"
id="status"
name="status"
:class="[settings.eqStatus ? 'checked' : '', 'carousel-page']"
v-model="settings.eqStatus"
/>
<label for="status">设备状态</label>
</div>
</div>
</div>
<div class="modal"></div>
<div class="footer">
<button @click="handleCancel" class="btn btn-cancel">取消</button>
<button @click="handleConfirm" class="btn btn-confirm">确认</button>
</div>
</div>
<div class="modal"></div>
</template>

<style scoped>
* {
user-select: none;
user-select: none;
}

.setting-dialog {
position: absolute;
margin: auto;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 577px;
height: 422px;
background: url(../assets/dialog-bg.png) 100% / contain no-repeat;
z-index: 1001;
transition: all .3s ease-out;
display: flex;
flex-direction: column;
gap: 18px;
padding: 24px 80px;
position: absolute;
margin: auto;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 577px;
height: 422px;
background: url(../assets/dialog-bg.png) 100% / contain no-repeat;
z-index: 1001;
transition: all 0.3s ease-out;
display: flex;
flex-direction: column;
gap: 12px;
padding: 24px 80px;
}

.main-content {
flex: 1;
padding-top: 10px;
flex: 1;
padding-top: 10px;
}

.form-item {
margin: 32px 0;
display: flex;
gap: 8px;
color: #fff;
font-size: 28px;
letter-spacing: 2px;
padding: 0 12px;
margin: 20px 0;
display: flex;
gap: 8px;
color: #fff;
font-size: 24px;
letter-spacing: 2px;
padding: 0 12px;
}

.form-item.selector {
gap: 32px;
gap: 32px;
}

.opt {
margin-left: 24px;
display: flex;
align-items: center;
gap: 8px;
display: flex;
align-items: center;
gap: 8px;
}

.opt2 {
font-size: 16px;
}

.form-item input {
flex: 1;
border: none;
appearance: none;
outline: none;
border-radius: 4px;
padding: 4px 12px;
font-size: 18px;
flex: 1;
border: none;
appearance: none;
outline: none;
border-radius: 4px;
padding: 4px 12px;
font-size: 18px;
}

input#resolution1,
input#resolution2 {
width: 10px;
width: 10px;
}

input[type="checkbox"] {
appearance: initial;
width: 24px;
height: 24px;
background: #fff;
flex: unset;
padding: unset;
font-size: unset;
cursor: pointer;
appearance: initial;
width: 24px;
height: 24px;
background: #fff;
flex: unset;
padding: unset;
font-size: unset;
cursor: pointer;
}

input[type="checkbox"].checked {
background: #0049ff;
position: relative;
background: #0049ff;
position: relative;
}

input[type="checkbox"].checked::after {
content: '\2713';
color: #fff;
font-size: 22px;
line-height: 24px;
text-align: center;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
content: "\2713";
color: #fff;
font-size: 22px;
line-height: 24px;
text-align: center;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}

.carousel-page__list {
display: flex;
gap: 8px;
flex-wrap: wrap;
font-size: 16px;
}

.carousel-page__list > div {
display: flex;
align-items: center;
gap: 8px;
}

input[type="checkbox"].carousel-page {
width: 18px;
height: 18px;
}
input[type="checkbox"].carousel-page.checked::after {
font-size: 14px;
line-height: 18px;
}

label {
cursor: pointer;
user-select: none;
cursor: pointer;
user-select: none;
}

.footer {
display: flex;
gap: 12px;
display: flex;
gap: 12px;
}

.btn {
flex: 1;
padding: 18px;
font-size: 28px;
cursor: pointer;
letter-spacing: 12px;
background: url(../assets/dialog-button.png) 0 0 / 100% 100% no-repeat;
flex: 1;
padding: 12px;
font-size: 20px;
cursor: pointer;
letter-spacing: 8px;
background: url(../assets/dialog-button.png) 0 0 / 100% 100% no-repeat;
}

button {
appearance: none;
outline: none;
background: none;
border: none;
color: #fff;
appearance: none;
outline: none;
background: none;
border: none;
color: #fff;
}

.modal {
/* position: fixed;
/* position: fixed;
height: 1080px;
width: 1920px; */
position: absolute;
height: 100%;
width: 100%;
left: 0;
top: 0;
background: #0003;
backdrop-filter: blur(3px);
z-index: 999;
transition: all .3s ease-out;
}
.setting-dialog>h1 {
text-align: center;
letter-spacing: 24px;
font-weight: 400;
text-shadow: 0 5px 1px #001124;
user-select: none;
color: #fff;
}
</style>
position: absolute;
height: 100%;
width: 100%;
left: 0;
top: 0;
background: #0003;
backdrop-filter: blur(3px);
z-index: 999;
transition: all 0.3s ease-out;
}
.setting-dialog > h1 {
text-align: center;
letter-spacing: 24px;
font-weight: 400;
text-shadow: 0 5px 1px #001124;
user-select: none;
color: #fff;
}
</style>

+ 1
- 1
src/main.js Переглянути файл

@@ -10,7 +10,7 @@ const pinia = createPinia();

setTimeout(() => {
window.location.reload();
}, 24 * 60 * 60 * 1000);
}, 60 * 60 * 1000);

const app = createApp(App);
app.use(pinia);


+ 15
- 0
src/store/settings.js Переглянути файл

@@ -13,6 +13,7 @@ export const useSettings = defineStore("settings", () => {
},
carousel: true,
carouselTime: 30, // s
carouselPages: ["3d", "data", "realtime", "alert", "announcement"],
fullscreen: false,
eqStatus: true,
}
@@ -70,6 +71,20 @@ export const useSettings = defineStore("settings", () => {
settings.value.resolution.height = value.height;
settings.value.resolution.width = value.width;
break;
case "carousel-page":
const exists = settings.value.carouselPages.includes(value);
if (exists)
settings.value.carouselPages = settings.value.carouselPages.filter(
(page) => page !== value
);
else {
settings.value.carouselPages.splice(
["3d", "data", "realtime", "alert", "announcement"].indexOf(value),
0,
value
);
}
break;
}
}
return { settings, updateSettings, rewriteSettings };


Завантаження…
Відмінити
Зберегти