完成水电表列表

This commit is contained in:
Zy
2026-04-18 18:14:07 +08:00
parent 9a95e2b7e3
commit d0888c6afb
115 changed files with 2842 additions and 343 deletions

View File

@@ -1,61 +1,23 @@
<template>
<!-- 👇 加这一层全局缩放容器 -->
<div class="global-scale-wrapper">
<div class="scale-content" :style="{ transform: `scale(${scale})` }">
<div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }">
<side-bar class="sidebar-container" />
<div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container">
<div>
<navbar ref="navbarRef" @set-layout="setLayout" />
</div>
<app-main />
<settings ref="settingRef" />
</div>
<div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }">
<side-bar class="sidebar-container" />
<div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container">
<div>
<navbar ref="navbarRef" @set-layout="setLayout" />
</div>
<app-main />
<settings ref="settingRef" />
</div>
</div>
</template>
<script lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
// 缩放比例
const scale = ref(1);
// 你的设计稿宽度(若伊默认1920,不用改)
const DESIGN_WIDTH = 1920;
// 计算缩放
const calcScale = () => {
const width = document.documentElement.clientWidth;
let ratio = width / DESIGN_WIDTH;
// 最小缩到0.7(防止太小看不清)
if (ratio < 0.7) ratio = 0.7;
// 最大不超过1(大屏不拉伸)
if (ratio > 1) ratio = 1;
scale.value = ratio;
console.log(scale.value);
};
// 监听窗口变化
let timer = null;
const resize = () => {
console.log(scale.value);
clearTimeout(timer);
timer = setTimeout(calcScale, 100);
};
onMounted(() => {
calcScale();
window.addEventListener('resize', resize);
});
onUnmounted(() => {
window.removeEventListener('resize', resize);
clearTimeout(timer);
});
</script>
<script setup lang="ts">
// ==========================================
// ✅ 第1步:统一 import
// ==========================================
import { ref, computed, watchEffect, onMounted, onUnmounted } from 'vue';
import { useWindowSize } from '@vueuse/core';
import SideBar from './components/Sidebar/index.vue';
import { AppMain, Navbar, Settings, TagsView } from './components';
import { useAppStore } from '@/store/modules/app';
@@ -64,6 +26,50 @@ import { NavTypeEnum } from '@/enums/NavTypeEnum';
import { initWebSocket } from '@/utils/websocket';
import { initSSE } from '@/utils/sse';
// ==========================================
// ✅ 第2步:缩放逻辑(从旧 script 移过来)
// ==========================================
const scale = ref(1);
const DESIGN_WIDTH = 1920;
const calcScale = () => {
const width = document.documentElement.clientWidth;
let ratio = width / DESIGN_WIDTH;
if (ratio < 0.7) ratio = 0.7;
if (ratio > 1) ratio = 1;
scale.value = ratio;
};
let timer: any = null;
const resize = () => {
clearTimeout(timer);
timer = setTimeout(calcScale, 100);
};
// ==========================================
// ✅ 第3步:生命周期钩子(统一写在这里)
// ==========================================
onMounted(() => {
// 缩放初始化
calcScale();
window.addEventListener('resize', resize);
// WebSocket
const protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
initWebSocket(protocol + window.location.host + import.meta.env.VITE_APP_BASE_API + '/resource/websocket');
// SSE
initSSE(import.meta.env.VITE_APP_BASE_API + '/resource/sse');
});
onUnmounted(() => {
window.removeEventListener('resize', resize);
clearTimeout(timer);
});
// ==========================================
// ✅ 第4步:原有业务逻辑
// ==========================================
const settingsStore = useSettingsStore();
const theme = computed(() => settingsStore.theme);
const sidebar = computed(() => useAppStore().sidebar);
@@ -72,7 +78,6 @@ const needTagsView = computed(() => settingsStore.tagsView);
const fixedHeader = computed(() => settingsStore.fixedHeader);
const layout = computed(() => settingsStore.navType);
// 根据布局模式判断是否显示侧边栏
const showSidebar = computed(() => {
if (sidebar.value.hide) return false;
return layout.value === NavTypeEnum.LEFT || layout.value === NavTypeEnum.MIX;
@@ -86,7 +91,7 @@ const classObj = computed(() => ({
}));
const { width } = useWindowSize();
const WIDTH = 992; // refer to Bootstrap's responsive design
const WIDTH = 992;
watchEffect(() => {
if (device.value === 'mobile') {
@@ -103,15 +108,6 @@ watchEffect(() => {
const navbarRef = ref<InstanceType<typeof Navbar>>();
const settingRef = ref<InstanceType<typeof Settings>>();
onMounted(() => {
const protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
initWebSocket(protocol + window.location.host + import.meta.env.VITE_APP_BASE_API + '/resource/websocket');
});
onMounted(() => {
initSSE(import.meta.env.VITE_APP_BASE_API + '/resource/sse');
});
const handleClickOutside = () => {
useAppStore().closeSideBar({ withoutAnimation: false });
};
@@ -125,25 +121,6 @@ const setLayout = () => {
@use '@/assets/styles/mixin.scss';
@use '@/assets/styles/variables.module.scss' as *;
// 全局缩放容器
.global-scale-wrapper {
width: 100vw;
height: 100vh;
overflow: hidden;
position: relative;
}
// // 缩放内容区
// .scale-content {
// width: 1920px;
// height: 100vh;
// position: absolute;
// left: 50%;
// top: 0;
// transform-origin: center center;
// margin-left: -960px; /* 1920/2 居中 */
// }
.app-wrapper {
@include mixin.clearfix;
position: relative;