Forráskód Böngészése

适配大屏版本

Hwf 6 hónapja
szülő
commit
c560b4cb83

+ 234 - 0
src/components/HeaderSection/index2.vue

@@ -0,0 +1,234 @@
+<template>
+  <div class="headerSection">
+    <div class="header-left">
+      <div class="menu">
+        <div
+          v-for="(item, index) in menuState.leftMenu"
+          :key="index"
+          :class="activeMenu === 'left' && activeMenuIndex === index ? 'menu-item active' : 'menu-item'"
+          :style="{ left: 400 * index + 'px' }"
+          @click="clickMenu(item)"
+        >
+          <div class="text">{{ item.label }}</div>
+        </div>
+      </div>
+    </div>
+    <div class="header-middle">
+      <div class="title"></div>
+    </div>
+    <div class="header-right">
+      <div class="menu">
+        <div
+          v-for="(item, index) in menuState.rightMenu"
+          :key="index"
+          :class="activeMenu === 'right' && activeMenuIndex === index ? 'menu-item active' : 'menu-item'"
+          :style="{ right: 400 * index + 'px' }"
+          @click="clickMenu(item)"
+        >
+          <div class="text">{{ item.label }}</div>
+        </div>
+      </div>
+      <div ref="userRef" class="userIcon" @click="handleShowBox">
+        <div v-show="showBox" class="log-out-box">
+          <div class="log-out" @click="handleShowTip">退出登录</div>
+        </div>
+      </div>
+    </div>
+    <Dialog v-model="showTip" class="tip" type="xs" title="提示" @close="showTip = false" @confirm="logout">确定注销并退出系统吗?</Dialog>
+  </div>
+</template>
+
+<script lang="ts" setup name="headerSection">
+import usePermissionStore from '@/store/modules/permission';
+import useUserStore from '@/store/modules/user';
+import { onClickOutside } from '@vueuse/core';
+
+const router = useRouter();
+const userStore = useUserStore();
+const permissionStore = usePermissionStore();
+const userRef = ref();
+// type 1 系统内地址 2 外链
+const menuState = computed(() => {
+  return permissionStore.menuState;
+});
+const activeMenu = computed(() => {
+  return permissionStore.activeMenu;
+});
+const activeMenuIndex = computed(() => {
+  return permissionStore.menuIndex;
+});
+
+// 点击菜单事件
+const clickMenu = (item) => {
+  if (!item.path) return;
+  if (item.type === '1') {
+    router.push({ path: item.path2 });
+  } else if (item.type === '2') {
+    window.location.href = item.path;
+  }
+};
+let showBox = ref(false);
+let showTip = ref(false);
+onClickOutside(userRef, (event) => {
+  showBox.value = false;
+});
+const handleShowBox = () => {
+  showBox.value = true;
+};
+const handleShowTip = () => {
+  showBox.value = false;
+  showTip.value = true;
+};
+const logout = async () => {
+  await userStore.logout();
+  location.href = import.meta.env.VITE_APP_CONTEXT_PATH + '#/';
+};
+</script>
+
+<style lang="scss" scoped>
+.headerSection {
+  width: 100%;
+  height: 228px;
+  padding: 0 69px;
+  display: flex;
+  //justify-content: space-between;
+  animation: fade 2s;
+  position: relative;
+  color: #fff;
+  font-family: 'YouSheBiaoTiHei';
+  .menu {
+    display: flex;
+    align-items: flex-start;
+    margin-top: 103px;
+    position: relative;
+    .menu-item {
+      width: 476px;
+      height: 120px;
+      position: absolute;
+      background-repeat: no-repeat;
+      background-size: 100% 100%;
+      cursor: pointer;
+      &:hover {
+        height: 166px;
+      }
+      .text {
+        width: 100%;
+        position: absolute;
+        top: 12px;
+        left: 0;
+        font-weight: 400;
+        font-size: 64px;
+        letter-spacing: 3px;
+        text-align: center;
+        cursor: pointer;
+      }
+    }
+    .active {
+      height: 166px;
+      .text {
+        top: 17px;
+      }
+    }
+  }
+  .header-left {
+    position: absolute;
+    left: 0;
+    z-index: 1;
+    .menu {
+      margin-left: 81px;
+      .menu-item {
+        background-image: url('@/assets/images/header/leftMenu.png');
+        background-repeat: no-repeat;
+        background-size: 100% 100%;
+        &:hover {
+          background-image: url('@/assets/images/header/leftMenuActive.png');
+        }
+      }
+      .active {
+        background-image: url('@/assets/images/header/leftMenuActive.png');
+      }
+    }
+  }
+  .header-middle {
+    position: absolute;
+    top: 0;
+    left: 50%;
+    transform: translateX(-50%);
+    background: url('@/assets/images/header/header.png') no-repeat;
+    background-size: 100% 100%;
+    width: 6814px;
+    height: 444px;
+    display: flex;
+    justify-content: center;
+    pointer-events: none;
+    .title {
+      margin-top: 60px;
+      width: 1314px;
+      height: 126px;
+      background: url('@/assets/images/header/title.png') no-repeat;
+      background-size: 100% 100%;
+    }
+  }
+  .header-right {
+    position: absolute;
+    right: 58px;
+    z-index: 1;
+    display: flex;
+    .menu {
+      .menu-item {
+        background-image: url('@/assets/images/header/rightMenu.png');
+        background-repeat: no-repeat;
+        background-size: 100% 100%;
+        &:hover {
+          background-image: url('@/assets/images/header/rightMenuActive.png');
+        }
+      }
+      .active {
+        background-image: url('@/assets/images/header/rightMenuActive.png');
+      }
+    }
+    .userIcon {
+      width: 68px;
+      height: 68px;
+      background-image: url('@/assets/images/header/user.png');
+      background-repeat: no-repeat;
+      background-size: 100% 100%;
+      margin-top: 54px;
+      margin-left: 57px;
+      margin-right: 57px;
+      cursor: pointer;
+      position: relative;
+      .log-out-box {
+        position: absolute;
+        bottom: -100px;
+        left: -30px;
+        border: 1px solid #2db3e9;
+        .log-out {
+          width: 200px;
+          display: flex;
+          flex-direction: column;
+          justify-content: center;
+          align-items: center;
+          padding: 20px 0;
+          color: #ffffff;
+          font-size: 38px;
+          background: #0d2c70;
+          cursor: pointer;
+          &:hover {
+            background: #1b4ea5;
+          }
+        }
+      }
+    }
+  }
+}
+
+@keyframes fade {
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: 1;
+  }
+}
+</style>

+ 7 - 1
src/components/Map/YztMap/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div ref="containerRef" class="map-container">
-    <div ref="mapRef" id="YztMap" class="map-container" :style="{ width: width, height: height }"></div>
+    <div ref="mapRef" id="YztMap" class="map-container" :style="{ width: width, height: height, transform: 'scale(' + inverseScale.inverseScaleX + ', ' + inverseScale.inverseScaleY + ')', transformOrigin: '0 0' }"></div>
     <!-- 右下工具  -->
         <div v-show="mapState.showScale" class="zoom-text">{{ mapState.zoom }}级</div>
     <div class="right-tool">
@@ -167,7 +167,13 @@ const handleShowMask = () => {
   emits('update:showMask', !props.showMask);
 };
 defineExpose({ addMarker, clearMarker });
+let inverseScale = ref({
+  inverseScaleX: 1,
+  inverseScaleY: 1
+});
 const handleResize = () => {
+  inverseScale.value.inverseScaleX = 1 / containerScale().scaleX;
+  inverseScale.value.inverseScaleY = 1 / containerScale().scaleY;
   const containerWidth = containerRef.value.clientWidth * containerScale().scaleX;
   const containerHeight = containerRef.value.clientHeight * containerScale().scaleY;
   width.value = containerWidth + 'px';

+ 10 - 0
src/router/index.ts

@@ -95,10 +95,20 @@ export const constantRoutes: RouteRecordRaw[] = [
     component: () => import('@/views/emergencyCommandMap/index.vue'),
     name: 'emergencyCommandMap'
   },
+  {
+    path: '/emergencyCommandMap2',
+    component: () => import('@/views/emergencyCommandMap/index2.vue'),
+    name: 'emergencyCommandMap2'
+  },
   {
     path: '/globalMap',
     component: () => import('@/views/globalMapPage/index.vue'),
     name: 'globalMap'
+  },
+  {
+    path: '/globalMap2',
+    component: () => import('@/views/globalMapPage/index2.vue'),
+    name: 'globalMap2'
   }
 ];
 

+ 3 - 3
src/store/modules/permission.ts

@@ -23,8 +23,8 @@ export const usePermissionStore = defineStore('permission', () => {
   // type 1 系统内地址 2 外链
   const menuState = reactive({
     leftMenu: [
-      { label: '全域地图', path: '/globalMap', type: '1', checked: false },
-      { label: '一图作战', path: '/', type: '1', checked: false },
+      { label: '全域地图', path: '/globalMap', path2: '/globalMap2', type: '1', checked: false },
+      { label: '一图作战', path: '/', path2: '/index2', type: '1', checked: false },
       { label: '总体态势', path: 'http://19.155.220.218/#/considerable-web/overallSituation?type=large', type: '2', checked: false },
       { label: '非煤矿山', path: 'http://19.155.220.218/#/considerable-web/noCoalMine?type=large', type: '2', checked: false },
       { label: '粉尘防爆', path: 'http://19.155.220.218/#/considerable-web/dustIgnitionPproof?type=large', type: '2', checked: false }
@@ -43,7 +43,7 @@ export const usePermissionStore = defineStore('permission', () => {
     let direction = '';
     let index = -1;
     for (let i = 0; i < menuState.leftMenu.length; i++) {
-      if (menuState.leftMenu[i].path === route.path) {
+      if (menuState.leftMenu[i].path === route.path || menuState.leftMenu[i].path2 === route.path) {
         index = i;
         direction = 'left';
         break;

+ 4 - 1
src/views/emergencyCommandMap/MiddleSection.vue

@@ -12,9 +12,12 @@
 <script lang="ts" setup>
 import GlobalMap from '@/views/globalMap/index.vue';
 import { useRouter } from 'vue-router';
+const props = defineProps({
+  flag: Boolean
+});
 const router = useRouter();
 const handleQuery1 = () => {
-  router.push({ path: '/' });
+  router.push({ path: props.flag ? '/index2' : '/' });
 };
 </script>
 

+ 121 - 0
src/views/emergencyCommandMap/index2.vue

@@ -0,0 +1,121 @@
+<template>
+  <div
+    id="dashboard-container"
+    ref="containerRef"
+    class="dashboard-container"
+    :style="{ transform: 'scale(' + scale.scaleX + ', ' + scale.scaleY + ')' }"
+  >
+    <div class="bg">
+      <HeaderSection />
+      <div class="dashboard-content">
+        <LeftSection v-show="showLeftSection" />
+        <MiddleSection :flag="true">
+          <i :class="showLeftSection ? 'arrow-icon left-icon' : 'arrow-icon right-icon'" @click="handleTelescoping('left')" />
+          <i :class="showRightSection ? 'arrow-icon2 right-icon' : 'arrow-icon2 left-icon'" @click="handleTelescoping('right')" />
+        </MiddleSection>
+        <RightSection v-show="showRightSection" :flag="true" />
+      </div>
+      <FooterSection style="position: absolute; bottom: 0; left: 0" />
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import HeaderSection from '@/components/HeaderSection/index2.vue';
+import LeftSection from './LeftSection/index.vue';
+import RightSection from './RightSection/index.vue';
+import MiddleSection from './MiddleSection.vue';
+import { getTransformScale } from '@/utils';
+import useAppStore from '@/store/modules/app';
+
+const appStore = useAppStore();
+const containerRef = ref();
+let scale = ref({ scaleX: 1, scaleY: 1 });
+let showLeftSection = computed(() => {
+  return appStore.showLeftSection;
+});
+let showRightSection = computed(() => {
+  return appStore.showRightSection;
+});
+const handleTelescoping = (type: string) => {
+  if (type === 'left') {
+    appStore.toggleLeftSection();
+  } else if (type === 'right') {
+    appStore.toggleRightSection();
+  }
+};
+provide('containerScale', () => scale.value);
+const resizeNumbers = () => {
+  const width = 8960;
+  const height = 2520;
+  const containerWidth = window.innerWidth;
+  const containerHeight = window.innerHeight;
+  const scaleX = containerWidth / width;
+  const scaleY = containerHeight / height;
+  scale.value = { scaleX: scaleX, scaleY: scaleY };
+};
+onMounted(() => {
+  scale.value = getTransformScale(containerRef.value);
+  resizeNumbers();
+  window.addEventListener('resize', resizeNumbers);
+});
+
+onUnmounted(() => {
+  window.removeEventListener('resize', resizeNumbers);
+});
+</script>
+
+<style lang="scss" scoped>
+.dashboard-container {
+  width: 8960px;
+  height: 2520px;
+  font-size: 36px;
+  font-family: 'PingFang SC', sans-serif;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  overflow: hidden;
+  transform-origin: 0 0;
+  .bg {
+    width: 100%;
+    background: url('@/assets/images/bg.jpg') no-repeat;
+    background-size: 100% 100%;
+    position: relative;
+  }
+  .dashboard-content {
+    padding: 0 81px;
+    display: flex;
+    height: calc(2520px - 228px);
+    overflow: hidden;
+  }
+}
+.left-icon {
+  background: url('@/assets/images/left.png') no-repeat;
+  background-size: 100% 100%;
+}
+
+.right-icon {
+  background: url('@/assets/images/right.png') no-repeat;
+  background-size: 100% 100%;
+}
+
+.arrow-icon {
+  position: absolute;
+  bottom: 180px;
+  left: 0;
+  z-index: 9;
+  width: 152px;
+  height: 158px;
+  cursor: pointer;
+}
+
+.arrow-icon2 {
+  position: absolute;
+  bottom: 180px;
+  right: 0;
+  z-index: 9;
+  width: 152px;
+  height: 158px;
+  cursor: pointer;
+}
+</style>

+ 71 - 0
src/views/globalMapPage/index2.vue

@@ -0,0 +1,71 @@
+<template>
+  <div
+    id="dashboard-container"
+    class="dashboard-container"
+    ref="containerRef"
+    :style="{ transform: 'scale(' + scale.scaleX + ', ' + scale.scaleY + ')' }"
+  >
+    <div class="bg">
+      <HeaderSection />
+      <div class="dashboard-content">
+        <GlobalMap />
+      </div>
+      <FooterSection style="position: absolute; bottom: 0; left: 0" />
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup name="globalMapPage">
+import HeaderSection from '@/components/HeaderSection/index2.vue';
+import GlobalMap from '@/views/globalMap/index.vue';
+import { getTransformScale } from '@/utils';
+
+const containerRef = ref();
+let scale = ref({ scaleX: 1, scaleY: 1 });
+
+provide('containerScale', () => scale.value);
+const resizeNumbers = () => {
+  const width = 8960;
+  const height = 2520;
+  const containerWidth = window.innerWidth;
+  const containerHeight = window.innerHeight;
+  const scaleX = containerWidth / width;
+  const scaleY = containerHeight / height;
+  scale.value = { scaleX: scaleX, scaleY: scaleY };
+};
+onMounted(() => {
+  scale.value = getTransformScale(containerRef.value);
+  resizeNumbers();
+  window.addEventListener('resize', resizeNumbers);
+});
+
+onUnmounted(() => {
+  window.removeEventListener('resize', resizeNumbers);
+});
+</script>
+
+<style lang="scss" scoped>
+.dashboard-container {
+  width: 8960px;
+  height: 2520px;
+  font-size: 36px;
+  font-family: 'PingFang SC', sans-serif;
+  position: relative;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  overflow: hidden;
+  transform-origin: 0 0;
+  .bg {
+    width: 100%;
+    background: url('@/assets/images/bg.jpg') no-repeat;
+    background-size: 100% 100%;
+    position: relative;
+  }
+  .dashboard-content {
+    display: flex;
+    height: calc(2520px - 228px);
+    overflow: hidden;
+  }
+}
+</style>

+ 4 - 2
src/views/routineCommandMap/MiddleSection.vue

@@ -5,7 +5,7 @@
       <div class="btn-active">备战防御</div>
       <div class="btn" style="margin-left: 40px" @click="handleQuery2">指挥调度</div>
     </div>
-    <PositionMap v-if="mapDialogVisible" v-model:visible="mapDialogVisible" />
+    <PositionMap v-if="mapDialogVisible" v-model:visible="mapDialogVisible" :flag="flag" />
     <slot />
   </div>
 </template>
@@ -14,7 +14,9 @@
 import GlobalMap from '../globalMap/index.vue';
 import { ref } from 'vue';
 import PositionMap from './PositionMap.vue';
-
+const props = defineProps({
+  flag: Boolean
+});
 const mapDialogVisible = ref(false);
 
 const handleQuery2 = () => {

+ 20 - 3
src/views/routineCommandMap/PositionMap.vue

@@ -59,7 +59,16 @@
     </el-form>
     <div ref="containerRef" class="map_box">
       <div id="positionMap">
-        <div id="map" class="map" :style="{ width: width, height: height }"></div>
+        <div
+          id="map"
+          class="map"
+          :style="{
+            width: width,
+            height: height,
+            transform: 'scale(' + inverseScale.inverseScaleX + ', ' + inverseScale.inverseScaleY + ')',
+            transformOrigin: '0 0'
+          }"
+        ></div>
       </div>
     </div>
   </Dialog>
@@ -76,10 +85,12 @@ const props = defineProps({
     default: () => {
       return false;
     }
-  }
+  },
+  flag: Boolean
 });
 const router = useRouter();
 const emits = defineEmits(['update:visible']);
+const containerScale = inject('containerScale');
 // 地图对象
 let map = null;
 let amap = {};
@@ -296,7 +307,13 @@ function handleClose() {
 }
 let queryFormRef = ref();
 let containerRef = ref();
+let inverseScale = ref({
+  inverseScaleX: 1,
+  inverseScaleY: 1
+});
 function handleResize() {
+  inverseScale.value.inverseScaleX = 1 / containerScale().scaleX;
+  inverseScale.value.inverseScaleY = 1 / containerScale().scaleY;
   const containerWidth = containerRef.value.clientWidth * (document.body.clientWidth / 8960);
   const containerHeight = containerRef.value.clientHeight * (document.body.clientHeight / 2520);
   width.value = containerWidth + 'px';
@@ -309,7 +326,7 @@ function submit() {
       console.log('提交数据', form);
       addEvent(form).then((res) => {
         router.push({
-          path: '/emergencyCommandMap',
+          path: props.flag ? '/emergencyCommandMap2' : '/emergencyCommandMap',
           query: {
             event_id: res.data
           }

+ 2 - 1
src/views/routineCommandMap/RightSection/EventReport/EventManage.vue

@@ -325,6 +325,7 @@ const props = defineProps<{
   modelValue?: boolean;
   title?: string;
   height?: string;
+  flag: boolean;
 }>();
 const emit = defineEmits(['update:modelValue']);
 
@@ -362,7 +363,7 @@ const enterCommand = (item) => {
     // 查看事件详情逻辑
     console.log('进入指挥', item);
     router.push({
-      path: '/emergencyCommandMap',
+      path: props.flag ? '/emergencyCommandMap2' : '/emergencyCommandMap',
       query: { event_id: item.event_id }
     });
   }

+ 5 - 2
src/views/routineCommandMap/RightSection/EventReport/index.vue

@@ -47,7 +47,7 @@
     </div>
   </div>
   <!--事件接报弹窗-->
-  <EventManage v-model="eventManageState.showListDialog" />
+  <EventManage v-model="eventManageState.showListDialog" :flag="flag" />
   <EventDetail v-if="eventDetailStatus.show" v-model="eventDetailStatus.show" :eventId="eventDetailStatus.id" :title="eventDetailStatus.title" />
 </template>
 
@@ -57,6 +57,9 @@ import { getEvent } from '@/api/duty/eventing';
 import EventManage from './EventManage.vue';
 import EventDetail from './EventDetail.vue';
 
+const props = defineProps({
+  flag: Boolean
+});
 const proxy = getCurrentInstance()?.proxy;
 const { mm_event_type, mm_event_level, mm_event_state, region } = toRefs<any>(
   proxy?.useDict('mm_event_type', 'mm_event_level', 'mm_event_state', 'region')
@@ -97,7 +100,7 @@ const enterCommand = (item) => {
   if (item) {
     // 查看事件详情逻辑
     router.push({
-      path: '/emergencyCommandMap',
+      path: props.flag ? '/emergencyCommandMap2' : '/emergencyCommandMap',
       query: { event_id: item.event_id }
     });
   }

+ 4 - 2
src/views/routineCommandMap/RightSection/index.vue

@@ -69,7 +69,7 @@
         </div>
       </div>
     </div>
-    <EventReport />
+    <EventReport :flag="flag" />
   </div>
 </template>
 
@@ -78,7 +78,9 @@ import EventReport from './EventReport/index.vue';
 import { option1 } from './chartOptions';
 import BigNumber from 'bignumber.js';
 import { getEventCount, getEventTypeCount } from '@/api/duty/eventing';
-
+const props = defineProps({
+  flag: Boolean
+});
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const { mm_event_type } = toRefs<any>(
   proxy?.useDict('mm_event_type')

+ 13 - 10
src/views/routineCommandMap/index2.vue

@@ -1,14 +1,19 @@
 <template>
-  <div id="dashboard-container" ref="containerRef" class="dashboard-container" :style="{ transform: 'scale(' + scale.scaleX + ', ' + scale.scaleY + ')' }">
+  <div
+    id="dashboard-container"
+    ref="containerRef"
+    class="dashboard-container"
+    :style="{ transform: 'scale(' + scale.scaleX + ', ' + scale.scaleY + ')' }"
+  >
     <div class="bg">
       <HeaderSection />
       <div class="dashboard-content">
         <LeftSection v-show="showLeftSection" />
-        <MiddleSection>
+        <MiddleSection :flag="true">
           <i :class="showLeftSection ? 'arrow-icon left-icon' : 'arrow-icon right-icon'" @click="handleTelescoping('left')" />
           <i :class="showRightSection ? 'arrow-icon2 right-icon' : 'arrow-icon2 left-icon'" @click="handleTelescoping('right')" />
         </MiddleSection>
-        <RightSection v-show="showRightSection" />
+        <RightSection v-show="showRightSection" :flag="true" />
       </div>
       <FooterSection style="position: absolute; bottom: 0; left: 0" />
     </div>
@@ -19,7 +24,7 @@
 import LeftSection from './LeftSection/index.vue';
 import RightSection from './RightSection/index.vue';
 import MiddleSection from './MiddleSection.vue';
-import autofit from 'autofit.js';
+import HeaderSection from '@/components/HeaderSection/index2.vue';
 import { getTransformScale } from '@/utils';
 import useAppStore from '@/store/modules/app';
 
@@ -40,9 +45,6 @@ const handleTelescoping = (type: string) => {
   }
 };
 provide('containerScale', () => scale.value);
-// const scaleStyle = () => {
-//   return '(' + scale.scaleX + ', ' + scale.scaleY + ')';
-// };
 const resizeNumbers = () => {
   const width = 8960;
   const height = 2520;
@@ -54,11 +56,12 @@ const resizeNumbers = () => {
 };
 onMounted(() => {
   scale.value = getTransformScale(containerRef.value);
-  resizeNumbers()
+  resizeNumbers();
+  window.addEventListener('resize', resizeNumbers);
 });
 
 onUnmounted(() => {
-
+  window.removeEventListener('resize', resizeNumbers);
 });
 </script>
 
@@ -71,7 +74,7 @@ onUnmounted(() => {
   justify-content: center;
   align-items: center;
   overflow: hidden;
-  transform-origin: 0px 0px;
+  transform-origin: 0 0;
   .bg {
     width: 100%;
     background: url('@/assets/images/bg.jpg') no-repeat;