zhangwencui
2026-05-29 0e66217cdb07d5e6bd337228e0eb39d67f877d0d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<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">
          <img :src="architectureImg"
               alt="系统架构图"
               class="architecture-img" />
        </div>
      </div>
    </div>
  </div>
</template>
 
<script setup>
  import { ref, onMounted, onBeforeUnmount, nextTick } from "vue";
  import architectureImg from "@/assets/images/xitongjiagou.svg";
 
  // 缩放比例
  const scaleRatio = ref(1);
  // 设计尺寸(基准尺寸)
  const designWidth = 1920;
  const designHeight = 980;
 
  // 计算缩放比例
  const calculateScale = () => {
    const container = document.querySelector(".scale-container");
    if (!container) return;
 
    // 获取容器的实际尺寸
    const containerWidth = container.clientWidth;
 
    if (containerWidth === 0) {
      // 如果还没渲染出来,延迟一下再计算
      setTimeout(calculateScale, 100);
      return;
    }
 
    // 计算宽度缩放比例,使其始终占满宽度
    const scaleX = containerWidth / designWidth;
    scaleRatio.value = scaleX;
  };
 
  // 窗口大小变化处理
  const handleResize = () => {
    calculateScale();
  };
 
  // 生命周期
  onMounted(() => {
    // 计算初始缩放比例
    nextTick(() => {
      calculateScale();
    });
 
    // 监听窗口大小变化
    window.addEventListener("resize", handleResize);
  });
 
  onBeforeUnmount(() => {
    window.removeEventListener("resize", handleResize);
  });
</script>
 
<style scoped lang="scss">
  .scale-container {
    position: relative;
    width: 100%;
    height: calc(100vh - 84px);
    background-color: #f5f7fa;
    overflow: hidden;
  }
 
  .architecture-scaling-container {
    position: relative;
    width: 1920px;
    height: 980px;
    transform-origin: left top;
    background-color: #f5f7fa;
    transition: transform 0.3s;
  }
 
  .architecture-container {
    padding: 20px;
    height: 100%;
    display: flex;
    flex-direction: column;
 
    .header {
      display: flex;
      align-items: center;
      margin-bottom: 20px;
      padding: 10px 20px;
      background: #fff;
      border-radius: 8px;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
 
      .title-bar {
        width: 4px;
        height: 20px;
        background-color: #409eff;
        margin-right: 12px;
        border-radius: 2px;
      }
 
      .title-text {
        margin: 0;
        font-size: 20px;
        font-weight: 600;
        color: #303133;
      }
    }
 
    .image-wrapper {
      flex: 1;
      background: #fff;
      border-radius: 8px;
      padding: 20px 40px;
      display: flex;
      justify-content: center;
      align-items: center;
      overflow: hidden;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
 
      .architecture-img {
        max-width: 100%;
        max-height: 100%;
        object-fit: contain;
      }
    }
  }
</style>