zhangwencui
2026-06-01 84cad75d6ee589ca6801bc3bb8649da424c2d73f
src/views/systemArchitecture/index.vue
@@ -1,24 +1,30 @@
<template>
  <div class="scale-container">
    <div class="architecture-scaling-container"
         :style="{ transform: `scale(${scaleRatio})` }">
      <div class="architecture-container">
        <div class="header">
          <span class="title-bar"></span>
          <h1 class="title-text">系统架构图</h1>
        </div>
        <div class="image-wrapper">
          <div class="hotspot-container">
            <img :src="architectureImg"
                 alt="系统架构图"
                 class="architecture-img" />
            <!-- 热点区域 -->
            <div v-for="spot in hotspots"
                 :key="spot.id"
                 class="hotspot"
                 :style="{ top: spot.top, left: spot.left, width: spot.width, height: spot.height }"
                 @click="handleSpotClick(spot)"
                 :title="'跳转至: ' + spot.name">
    <div class="scroll-content"
         :style="{
           height: `${designHeight * scaleRatio}px`,
           width: `${designWidth * scaleRatio}px`
         }">
      <div class="architecture-scaling-container"
           :style="{ transform: `scale(${scaleRatio})` }">
        <div class="architecture-container">
          <div class="header">
            <span class="title-bar"></span>
            <h1 class="title-text">系统架构图</h1>
          </div>
          <div class="image-wrapper">
            <div class="hotspot-container">
              <img :src="architectureImg"
                   alt="系统架构图"
                   class="architecture-img" />
              <!-- 热点区域 -->
              <div v-for="spot in hotspots"
                   :key="spot.id"
                   class="hotspot"
                   :style="{ top: spot.top, left: spot.left, width: spot.width, height: spot.height }"
                   @click="handleSpotClick(spot)"
                   :title="'跳转至: ' + spot.name">
              </div>
            </div>
          </div>
        </div>
@@ -255,16 +261,18 @@
    // 获取容器的实际尺寸
    const containerWidth = container.clientWidth;
    const containerHeight = container.clientHeight;
    if (containerWidth === 0) {
    if (containerWidth === 0 || containerHeight === 0) {
      // 如果还没渲染出来,延迟一下再计算
      setTimeout(calculateScale, 100);
      return;
    }
    // 计算宽度缩放比例,使其始终占满宽度
    // 计算缩放比例,取宽高比例中的较大值,确保始终撑满整个容器
    const scaleX = containerWidth / designWidth;
    scaleRatio.value = scaleX;
    const scaleY = containerHeight / designHeight;
    scaleRatio.value = Math.max(scaleX, scaleY);
  };
  // 窗口大小变化处理
@@ -273,6 +281,7 @@
  };
  // 生命周期
  let resizeObserver = null;
  onMounted(() => {
    // 计算初始缩放比例
    nextTick(() => {
@@ -281,10 +290,22 @@
    // 监听窗口大小变化
    window.addEventListener("resize", handleResize);
    // 使用 ResizeObserver 监听容器尺寸变化(解决侧边栏切换问题)
    const container = document.querySelector(".scale-container");
    if (container && window.ResizeObserver) {
      resizeObserver = new ResizeObserver(() => {
        calculateScale();
      });
      resizeObserver.observe(container);
    }
  });
  onBeforeUnmount(() => {
    window.removeEventListener("resize", handleResize);
    if (resizeObserver) {
      resizeObserver.disconnect();
    }
  });
</script>
@@ -294,11 +315,21 @@
    width: 100%;
    height: calc(100vh - 84px);
    background-color: #f5f7fa;
    overflow: hidden;
    overflow: auto;
    display: flex;
    justify-content: center;
    align-items: flex-start;
  }
  .scroll-content {
    position: relative;
    flex-shrink: 0;
  }
  .architecture-scaling-container {
    position: relative;
    position: absolute;
    top: 0;
    left: 0;
    width: 1920px;
    height: 980px;
    transform-origin: left top;