Bläddra i källkod

[Mod 0000] 修改张家峁页面样式和内容

wangkeyi 3 dagar sedan
förälder
incheckning
cdede03cfd
26 ändrade filer med 409 tillägg och 887 borttagningar
  1. BIN
      src/assets/images/vent/home/selfIgnition/card-bg.png
  2. 0 9
      src/assets/images/vent/home/selfIgnition/form-icon.svg
  3. 9 0
      src/assets/images/vent/home/selfIgnition/goaf-stat-closed.svg
  4. 14 0
      src/assets/images/vent/home/selfIgnition/goaf-stat-mining.svg
  5. 13 0
      src/assets/images/vent/home/selfIgnition/goaf-stat-stopped.svg
  6. 1 1
      src/assets/images/vent/home/selfIgnition/goaf-stat-total.svg
  7. 9 0
      src/assets/images/vent/home/selfIgnition/goaf-stat-withdraw.svg
  8. 0 18
      src/assets/images/vent/home/selfIgnition/info-icon.svg
  9. 0 9
      src/assets/images/vent/home/selfIgnition/install-wind-speed.svg
  10. 0 8
      src/assets/images/vent/home/selfIgnition/install-wind-volume.svg
  11. 3 0
      src/assets/images/vent/home/selfIgnition/level-safety-orange.svg
  12. 3 0
      src/assets/images/vent/home/selfIgnition/level-warning-orange.svg
  13. BIN
      src/assets/images/vent/home/selfIgnition/list-icon-bg.png
  14. BIN
      src/assets/images/vent/home/selfIgnition/overall-bar-glow.png
  15. BIN
      src/assets/images/vent/home/selfIgnition/overall-label-bg.png
  16. BIN
      src/assets/images/vent/home/selfIgnition/result-block-bg.png
  17. BIN
      src/assets/images/vent/home/selfIgnition/submit-glow.png
  18. BIN
      src/assets/images/vent/home/selfIgnition/tab-bg.png
  19. 43 49
      src/views/vent/home/selfIgnition/components/ManualView.vue
  20. 94 166
      src/views/vent/home/selfIgnition/components/MonitorView.vue
  21. 149 43
      src/views/vent/home/selfIgnition/components/OverviewView.vue
  22. 1 2
      src/views/vent/home/selfIgnition/components/PanelSelect.vue
  23. 1 514
      src/views/vent/home/selfIgnition/data.ts
  24. 16 18
      src/views/vent/home/selfIgnition/goafOverview.adapter.ts
  25. 52 49
      src/views/vent/home/selfIgnition/index.vue
  26. 1 1
      src/views/vent/home/selfIgnition/safetyEvaluation.api.ts

BIN
src/assets/images/vent/home/selfIgnition/card-bg.png


+ 0 - 9
src/assets/images/vent/home/selfIgnition/form-icon.svg

@@ -1,9 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="15.267" height="17.644" viewBox="0 0 15.267 17.644">
-  <defs>
-    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
-      <stop offset="0" stop-color="#3df6ff"/>
-      <stop offset="1" stop-color="#b3fff5"/>
-    </linearGradient>
-  </defs>
-  <path id="路径_58015" data-name="路径 58015" d="M136.97,64a.476.476,0,0,1,.476.476v.238a.477.477,0,0,0,.476.476h3.87a.477.477,0,0,1,.476.476v6.122a.476.476,0,0,1-.476.476h-.238a.476.476,0,0,1-.476-.476V66.853a.476.476,0,0,0-.476-.476h-1.427a.476.476,0,0,0-.476.476V68.28a.476.476,0,0,1-.476.476h-6.182a.476.476,0,0,1-.476-.476V66.853a.476.476,0,0,0-.476-.476h-1.427a.476.476,0,0,0-.476.476V78.98a.477.477,0,0,0,.476.476h3.8a.477.477,0,0,1,.476.476v.238a.476.476,0,0,1-.476.476h-4.993a.476.476,0,0,1-.476-.476v-14.5a.477.477,0,0,1,.476-.476h3.8a.476.476,0,0,0,.476-.476v-.238a.477.477,0,0,1,.476-.476Zm4.475,9.848.485.485a.476.476,0,0,1,.061.6l-.059.075-5.288,5.285a.476.476,0,0,1-.253.132l-.923.163a.238.238,0,0,1-.276-.275l.162-.924a.476.476,0,0,1,.133-.254l5.286-5.285a.476.476,0,0,1,.673,0Zm-7.976,2.041a.477.477,0,0,1,.476.476V76.6a.476.476,0,0,1-.476.476h-1.427a.476.476,0,0,1-.476-.476v-.238a.477.477,0,0,1,.476-.476Zm2.378-2.378a.477.477,0,0,1,.476.476v.238a.476.476,0,0,1-.476.476h-3.8a.476.476,0,0,1-.476-.476v-.238a.477.477,0,0,1,.476-.476Zm2.378-2.378a.477.477,0,0,1,.476.476v.238a.476.476,0,0,1-.476.476h-6.182a.476.476,0,0,1-.476-.476v-.238a.477.477,0,0,1,.476-.476Zm-2.14-5.944H134.23a.238.238,0,0,0-.238.238v.713a.238.238,0,0,1-.238.238h-.769a.238.238,0,0,0-.238.238v.713a.238.238,0,0,0,.238.238h4.288a.238.238,0,0,0,.238-.238v-.713a.238.238,0,0,0-.238-.238h-.713a.238.238,0,0,1-.238-.238v-.713A.238.238,0,0,0,136.084,65.189Z" transform="translate(-127.5 -63.5)" stroke="rgba(0,0,0,0)" stroke-width="1" fill="url(#linear-gradient)"/>
-</svg>

+ 9 - 0
src/assets/images/vent/home/selfIgnition/goaf-stat-closed.svg

@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="22.367" height="22.367" viewBox="0 0 22.367 22.367">
+  <defs>
+    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
+      <stop offset="0" stop-color="#abdcff"/>
+      <stop offset="1" stop-color="#fff"/>
+    </linearGradient>
+  </defs>
+  <path id="路径_58069" data-name="路径 58069" d="M78.256,67.544A10.683,10.683,0,1,0,67.572,78.227,10.683,10.683,0,0,0,78.256,67.544ZM64.9,59.223a8.756,8.756,0,0,1,5.352,0,.444.444,0,0,0-.005.067V75.8a.379.379,0,0,0,.005.069,8.769,8.769,0,0,1-5.352,0A.444.444,0,0,0,64.9,75.8V59.29a.442.442,0,0,0-.005-.069Zm-1.937.9a8.742,8.742,0,0,0,0,14.851V60.118Zm13.353,7.426a8.734,8.734,0,0,1-4.128,7.425V60.119A8.731,8.731,0,0,1,76.312,67.545Z" transform="translate(-56.389 -56.36)" stroke="rgba(0,0,0,0)" stroke-width="1" fill="url(#linear-gradient)"/>
+</svg>

+ 14 - 0
src/assets/images/vent/home/selfIgnition/goaf-stat-mining.svg

@@ -0,0 +1,14 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="17.797" height="15.727" viewBox="0 0 17.797 15.727">
+  <defs>
+    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
+      <stop offset="0" stop-color="#abdcff"/>
+      <stop offset="1" stop-color="#fff"/>
+    </linearGradient>
+  </defs>
+  <g id="组_16943" data-name="组 16943" transform="translate(0.083)">
+    <path id="路径_58071" data-name="路径 58071" d="M856.147,23.258h4.289V38.271h-4.289Z" transform="translate(-843.079 -22.9)" fill="url(#linear-gradient)"/>
+    <path id="路径_58072" data-name="路径 58072" d="M-.083,0h17.8V.714H-.083Zm0,15.013h17.8v.714H-.083Z" transform="translate(0)" fill="url(#linear-gradient)"/>
+    <path id="路径_58073" data-name="路径 58073" d="M832.89,0h.714V15.727h-.714Zm4.289,0h.714V15.727h-.714Z" transform="translate(-820.179)" fill="url(#linear-gradient)"/>
+    <path id="路径_58074" data-name="路径 58074" d="M4.289,238.3v2.86L0,238.3v-2.86l4.289-2.86v2.86h7.865v2.86H4.29Z" transform="translate(-0.081 -229.005)" fill="url(#linear-gradient)"/>
+  </g>
+</svg>

+ 13 - 0
src/assets/images/vent/home/selfIgnition/goaf-stat-stopped.svg

@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20.499" height="20.46" viewBox="0 0 20.499 20.46">
+  <defs>
+    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
+      <stop offset="0" stop-color="#abdcff"/>
+      <stop offset="1" stop-color="#fff"/>
+    </linearGradient>
+  </defs>
+  <g id="组_16944" data-name="组 16944" transform="translate(-61.7 -64.4)">
+    <path id="路径_58075" data-name="路径 58075" d="M81,72.052Zm-4.062.817a6.856,6.856,0,0,1,1.585.187L74.677,64.4,68.19,74.134,65.755,70.89,61.7,79h8.538A6.73,6.73,0,0,1,76.942,72.869Zm-6.656,7.755H62.511v1.621h8.236A6.678,6.678,0,0,1,70.286,80.624Z" transform="translate(0)" fill="url(#linear-gradient)"/>
+    <path id="路径_58076" data-name="路径 58076" d="M504.257,500a5.257,5.257,0,1,0,5.257,5.257A5.255,5.255,0,0,0,504.257,500Zm0,9.259a4.005,4.005,0,1,1,4.005-4.005A4.006,4.006,0,0,1,504.257,509.26Z" transform="translate(-427.314 -425.653)" fill="url(#linear-gradient)"/>
+    <path id="路径_58077" data-name="路径 58077" d="M612.88,707.27h-4.195a.685.685,0,1,1,0-1.37h4.2a.685.685,0,1,1,0,1.37Z" transform="translate(-533.825 -626.852)" fill="url(#linear-gradient)"/>
+  </g>
+</svg>

+ 1 - 1
src/assets/images/vent/home/selfIgnition/goaf-icon.svg → src/assets/images/vent/home/selfIgnition/goaf-stat-total.svg

@@ -5,5 +5,5 @@
       <stop offset="1" stop-color="#fff"/>
     </linearGradient>
   </defs>
-  <path id="路径_58031" data-name="路径 58031" d="M160.223,312.65l-.88,4.26a4,4,0,0,1-3.776,3.428,20.444,20.444,0,0,1-6.752,0,4,4,0,0,1-3.775-3.427h0a3.558,3.558,0,0,1,0-.775l-.019-3.285-.035-.2h-3.865V327.2h22.971V312.65h-3.865Z" transform="translate(-140.617 -312.15)" stroke="rgba(0,0,0,0)" stroke-width="1" fill="url(#linear-gradient)"/>
+  <path id="路径_58009" data-name="路径 58009" d="M160.223,312.65l-.88,4.26a4,4,0,0,1-3.776,3.428,20.444,20.444,0,0,1-6.752,0,4,4,0,0,1-3.775-3.427h0a3.558,3.558,0,0,1,0-.775l-.019-3.285-.035-.2h-3.865V327.2h22.971V312.65h-3.865Z" transform="translate(-140.617 -312.15)" stroke="rgba(0,0,0,0)" stroke-width="1" fill="url(#linear-gradient)"/>
 </svg>

+ 9 - 0
src/assets/images/vent/home/selfIgnition/goaf-stat-withdraw.svg

@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="22.535" height="17.503" viewBox="0 0 22.535 17.503">
+  <defs>
+    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
+      <stop offset="0" stop-color="#abdcff"/>
+      <stop offset="1" stop-color="#fff"/>
+    </linearGradient>
+  </defs>
+  <path id="路径_58070" data-name="路径 58070" d="M50.082,40.99,56.575,34.5l1.838,1.838-2.205,2.205h8.577a6.126,6.126,0,0,1,0,12.252H53.758v-2.45H64.784a3.676,3.676,0,0,0,0-7.351h-14.7Z" transform="translate(-48.875 -33.788)" stroke="rgba(0,0,0,0)" stroke-width="1" fill="url(#linear-gradient)"/>
+</svg>

+ 0 - 18
src/assets/images/vent/home/selfIgnition/info-icon.svg

@@ -1,18 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="12.369" height="11.645" viewBox="0 0 12.369 11.645">
-  <defs>
-    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
-      <stop offset="0" stop-color="#3df6ff"/>
-      <stop offset="1" stop-color="#b3fff5"/>
-    </linearGradient>
-  </defs>
-  <g id="组_16798" data-name="组 16798" transform="translate(-64 -90.24)">
-    <path id="路径_58016" data-name="路径 58016" d="M420.1,90.24h2.485V99.4H420.1Z" transform="translate(-351.18)" fill="url(#linear-gradient)"/>
-    <path id="路径_58017" data-name="路径 58017" d="M180.224,397.632h2.484v4.917h-2.484Z" transform="translate(-114.62 -303.148)" fill="url(#linear-gradient)"/>
-    <path id="路径_58018" data-name="路径 58018" d="M660.032,278.656h2.485v6.56h-2.485Z" transform="translate(-587.804 -185.815)" fill="url(#linear-gradient)"/>
-    <path id="路径_58019" data-name="路径 58019" d="M64,816.64H76.369v1.617H64Z" transform="translate(0 -716.372)" fill="url(#linear-gradient)"/>
-    <path id="路径_58020" data-name="路径 58020" d="M485.76,159.616h1.579v8.2H485.76Z" transform="translate(-415.938 -68.418)" fill="url(#linear-gradient)"/>
-    <path id="路径_58021" data-name="路径 58021" d="M245.824,465.152H247.4v3.986h-1.579Z" transform="translate(-179.314 -369.736)" fill="url(#linear-gradient)"/>
-    <path id="路径_58022" data-name="路径 58022" d="M725.7,341.44h1.579v5.692H725.7Z" transform="translate(-652.561 -247.732)" fill="url(#linear-gradient)"/>
-    <path id="路径_58023" data-name="路径 58023" d="M123.072,875.648h11.554v.8H123.072Z" transform="translate(-58.257 -774.566)" fill="url(#linear-gradient)"/>
-  </g>
-</svg>

+ 0 - 9
src/assets/images/vent/home/selfIgnition/install-wind-speed.svg

@@ -1,9 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20.211" height="20.099" viewBox="0 0 20.211 20.099">
-  <defs>
-    <linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
-      <stop offset="0" stop-color="#2cfff1"/>
-      <stop offset="1" stop-color="#ccedff"/>
-    </linearGradient>
-  </defs>
-  <path id="路径_58056" data-name="路径 58056" d="M15.25,1.189a4.4,4.4,0,0,0-4.356,3.794.8.8,0,0,0-.023.172l-.023.268H10.9a.852.852,0,0,0,1.641,0h.013l.023-.2a2.683,2.683,0,1,1,2.653,3.062H3.911a.861.861,0,1,0,0,1.722h11.58v0a4.411,4.411,0,0,0-.241-8.818ZM3.915,6.724H7.869V6.7A3.355,3.355,0,0,0,7.543,0H7.507A3.34,3.34,0,0,0,4.179,3.318V3.6h.034a.852.852,0,0,0,.792.6.82.82,0,0,0,.615-.232A.962.962,0,0,0,5.855,3.6h.028V3.365A1.641,1.641,0,1,1,7.524,5H3.911a.852.852,0,1,0,0,1.7Zm-2.5,4.809a.852.852,0,1,0,.862.852.867.867,0,0,0-.852-.852Zm0-3.26a.852.852,0,1,0,.862.852.875.875,0,0,0-.852-.852Zm0-3.27a.852.852,0,1,0,.862.862A.869.869,0,0,0,1.412,5Zm11.426,6.564v-.023H3.911a.861.861,0,1,0,0,1.722h8.5a2.061,2.061,0,1,1-2.054,2.063V15.1h-.034a.869.869,0,0,0-.792-.607H9.5a.852.852,0,0,0-.815.607H8.65v.266a3.779,3.779,0,0,0,3.57,3.736h.213a3.734,3.734,0,0,0,2.514-.967,3.779,3.779,0,0,0-2.106-6.564Z" transform="translate(-0.071 0.501)" stroke="rgba(0,0,0,0)" stroke-miterlimit="10" stroke-width="1" fill="url(#linear-gradient)"/>
-</svg>

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 8
src/assets/images/vent/home/selfIgnition/install-wind-volume.svg


+ 3 - 0
src/assets/images/vent/home/selfIgnition/level-safety-orange.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="11.832" height="14.462" viewBox="0 0 11.832 14.462">
+  <path id="路径_58053" data-name="路径 58053" d="M139.7,44.113a.625.625,0,0,0-.362-.23l-5.423-1.216-5.39,1.216a.61.61,0,0,0-.394.23.7.7,0,0,0-.131.394v6.574a4.151,4.151,0,0,0,.46,1.873,4.063,4.063,0,0,0,1.282,1.413l4.174,2.761,4.174-2.761a3.91,3.91,0,0,0,1.742-3.287V44.507a.7.7,0,0,0-.131-.394Zm-1.183,6.968a2.79,2.79,0,0,1-.3,1.249,2.4,2.4,0,0,1-.855.953l-3.418,2.3V49.24h-4.634V45.033l4.6-1.019V49.24h4.6Z" transform="translate(-128 -42.667)" fill="#ff9d1c"/>
+</svg>

+ 3 - 0
src/assets/images/vent/home/selfIgnition/level-warning-orange.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="13.607" height="13.627" viewBox="0 0 13.607 13.627">
+  <path id="路径_58048" data-name="路径 58048" d="M16.916,12.639h-.987V8.068a4.7,4.7,0,1,1,9.394,0v4.57H16.916Zm4.05-7.374L18.649,9.08H20.5l-.464,2.862,2.317-3.816H20.5l.464-2.862Zm3.553-4.192a.458.458,0,0,1,.166.624l-.833,1.448-.787-.456L23.9,1.24a.453.453,0,0,1,.618-.168h0ZM20.625,0a.476.476,0,0,1,.493.46V2.1h-.985V.459A.476.476,0,0,1,20.625,0ZM16.733,1.072a.454.454,0,0,1,.621.166l.833,1.448-.787.456-.834-1.449a.456.456,0,0,1,.167-.622ZM13.884,3.934a.453.453,0,0,1,.621-.166l1.443.837-.454.79L14.05,4.557a.456.456,0,0,1-.166-.622Zm13.485,0a.458.458,0,0,1-.167.624l-1.442.836-.454-.79,1.442-.837a.454.454,0,0,1,.619.165s0,0,0,0Zm-13.049,8.7H26.934a.494.494,0,1,1,0,.988H14.32a.494.494,0,1,1,0-.988Z" transform="translate(-13.822)" fill="#ff9d1c"/>
+</svg>

BIN
src/assets/images/vent/home/selfIgnition/list-icon-bg.png


BIN
src/assets/images/vent/home/selfIgnition/overall-bar-glow.png


BIN
src/assets/images/vent/home/selfIgnition/overall-label-bg.png


BIN
src/assets/images/vent/home/selfIgnition/result-block-bg.png


BIN
src/assets/images/vent/home/selfIgnition/submit-glow.png


BIN
src/assets/images/vent/home/selfIgnition/tab-bg.png


+ 43 - 49
src/views/vent/home/selfIgnition/components/ManualView.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="ignition-view manual-view">
     <!-- 左:人工录入 -->
-    <Module :x="20" :y="132" :width="393" :height="907" title="人工录入">
+    <Module :x="20" :y="144" :width="393" :height="766" title="人工录入">
       <div class="manual-form">
         <div class="form-toolbar">
           <div class="eval-type-tabs">
@@ -48,7 +48,7 @@
     </Module>
 
     <!-- 右:评价结果 -->
-    <Module :x="1505" :y="132" :width="393" :height="907" title="评价结果">
+    <Module :x="1505" :y="144" :width="393" :height="766" title="评价结果">
       <div class="result-panel">
         <div class="result-top">
           <div class="score-line">
@@ -517,7 +517,7 @@
   .field-list {
     display: flex;
     flex-direction: column;
-    gap: 7px;
+    gap: 12px;
   }
 
   .field-row {
@@ -525,7 +525,12 @@
     align-items: center;
     gap: 6px;
     min-width: 0;
-    min-height: 42px;
+    min-height: 34px;
+    padding: 0 8px;
+    box-sizing: border-box;
+    border-radius: 2px;
+    // 设计稿:整行铺一条左亮右暗的渐变底
+    background: linear-gradient(90deg, rgba(32, 115, 175, 0.48) 0%, rgba(16, 62, 100, 0.22) 55%, rgba(10, 40, 70, 0.06) 100%);
 
     :deep(.ignition-select) {
       flex: 1;
@@ -538,7 +543,7 @@
   .field-label {
     width: 126px;
     flex: none;
-    text-align: right;
+    text-align: left;
     color: #fff;
     font-size: 12px;
     line-height: 1.3;
@@ -581,31 +586,35 @@
     display: flex;
     flex-direction: column;
     height: 100%;
-    padding: 28px 12px 0;
+    padding: 24px 10px 0;
     box-sizing: border-box;
   }
 
   .result-top {
     flex: none;
-    padding: 0 16px;
+    padding: 0 14px;
   }
 
   .score-line {
     display: flex;
     align-items: baseline;
-    justify-content: space-between;
   }
 
   .score-label {
+    flex: none;
+    white-space: nowrap;
     color: #fff;
-    font-size: 34px;
+    font-size: 26px;
     line-height: 1;
     letter-spacing: 1px;
   }
 
   .score-value {
+    // 占满标签之外的剩余空间并居中
+    flex: 1 1 auto;
+    text-align: center;
     color: #fff;
-    font-size: 54px;
+    font-size: 49px;
     font-weight: 700;
     line-height: 1;
     letter-spacing: 1px;
@@ -615,15 +624,15 @@
   .gauge-line {
     display: flex;
     align-items: center;
-    justify-content: space-between;
-    margin-top: 12px;
+    margin-top: 10px;
   }
 
   .gauge {
     display: flex;
+    flex: 0 0 50%;
     align-items: center;
-    width: 149px;
-    height: 27px;
+    min-width: 0;
+    height: 23px;
   }
 
   .gauge-segment {
@@ -635,13 +644,13 @@
   .risk-tag {
     display: flex;
     align-items: center;
+    flex: 0 0 50%;
     justify-content: center;
-    width: 159px;
-    height: 34px;
-    padding: 0 12px 0 6px;
+    height: 29px;
+    padding: 0 10px 0 5px;
     box-sizing: border-box;
     color: #fff;
-    font-size: 19px;
+    font-size: 16px;
     font-weight: 600;
     letter-spacing: 0.5px;
     white-space: nowrap;
@@ -655,10 +664,10 @@
     display: flex;
     flex-direction: column;
     justify-content: center;
-    width: calc(100% - 18px);
-    height: 139px;
-    margin: 38px auto 0;
-    padding: 0 20px;
+    width: calc(100% - 15px);
+    height: 119px;
+    margin: 33px auto 0;
+    padding: 0 17px;
     box-sizing: border-box;
     background: url('@/assets/images/vent/home/selfIgnition/result-top-bg.png') no-repeat center / 100% 100%;
   }
@@ -667,22 +676,22 @@
     display: flex;
     align-items: center;
     justify-content: space-between;
-    height: 34px;
+    height: 29px;
     color: #fff;
-    font-size: 19px;
+    font-size: 17px;
     letter-spacing: 0.5px;
 
     em {
       color: #3df6ff;
       font-style: normal;
-      font-size: 19px;
+      font-size: 17px;
       text-shadow: 0 0 8px rgba(61, 246, 255, 0.35);
     }
   }
 
   .level-table {
     flex: none;
-    margin-top: 33px;
+    margin-top: 28px;
   }
 
   .level-head,
@@ -693,9 +702,9 @@
   }
 
   .level-head {
-    height: 32px;
+    height: 27px;
     color: #3df6ff;
-    font-size: 17px;
+    font-size: 14px;
     background: url('@/assets/images/vent/home/selfIgnition/result-table-head.png') no-repeat center / 100% 100%;
 
     span:nth-child(1) {
@@ -713,10 +722,10 @@
 
   .level-row {
     position: relative;
-    height: 59px;
+    height: 51px;
     color: #e8f8ff;
-    font-size: 17px;
-    background: url('@/assets/images/vent/home/selfIgnition/result-row-glow.png') no-repeat center bottom / 100% 25px;
+    font-size: 14px;
+    background: url('@/assets/images/vent/home/selfIgnition/result-row-glow.png') no-repeat center bottom / 100% 21px;
 
     span:nth-child(1) {
       width: 36%;
@@ -747,12 +756,12 @@
     display: flex;
     align-items: center;
     justify-content: center;
-    gap: 7px;
+    gap: 6px;
 
     i {
       flex: none;
-      width: 9px;
-      height: 9px;
+      width: 8px;
+      height: 8px;
       border-radius: 50%;
     }
 
@@ -787,21 +796,6 @@
     &:disabled {
       opacity: 0.5;
       cursor: not-allowed;
-
-      &::after {
-        display: none;
-      }
-    }
-
-    &::after {
-      content: '';
-      position: absolute;
-      left: 0;
-      right: 0;
-      bottom: -8px;
-      height: 16px;
-      background: url('@/assets/images/vent/home/selfIgnition/submit-glow.png') no-repeat center / 100% 100%;
-      pointer-events: none;
     }
   }
 </style>

+ 94 - 166
src/views/vent/home/selfIgnition/components/MonitorView.vue

@@ -1,7 +1,7 @@
 <template>
   <div ref="viewRef" class="ignition-view monitor-view">
     <!-- 左上:自然发火阶段 -->
-    <Module :x="20" :y="132" :width="393" :height="578" title="自然发火阶段">
+    <Module :x="20" :y="144" :width="393" :height="497" title="自然发火阶段">
       <div class="stage-panel">
         <span class="stage-emblem">
           <img class="stage-emblem-frame" src="@/assets/images/vent/home/selfIgnition/2-1.png" alt="" />
@@ -34,10 +34,10 @@
     </Module>
 
     <!-- 右上:传感器监测 -->
-    <Module :x="1505" :y="77" :width="393" :height="328" title="传感器监测">
+    <Module :x="1505" :y="98" :width="393" :height="282" title="传感器监测">
       <div v-if="displaySensorGroups.length" class="sensor-panel">
         <div v-for="group in displaySensorGroups" :key="group.name" class="sensor-group">
-          <div class="sensor-group-title">{{ group.name }}</div>
+          <div class="sensor-group-title">{{ sceneName || group.name }}</div>
           <div v-for="row in group.rows" :key="row.label" class="sensor-row">
             <span :title="row.label">{{ row.label }}:</span>
             <em>{{ row.value }}</em>
@@ -51,7 +51,7 @@
     </Module>
 
     <!-- 右中:光纤测温 -->
-    <Module class="fiber-module" :x="1505" :y="420" :width="393" :height="290" title="光纤测温">
+    <Module class="fiber-module" :x="1505" :y="393" :width="393" :height="249" title="光纤测温">
       <div v-if="displayFiberData.solid.length" class="fiber-panel">
         <div v-if="fiberOptions.length > 1" class="fiber-toolbar">
           <span class="fiber-toolbar-label">光纤设备</span>
@@ -84,7 +84,7 @@
     </Module>
 
     <!-- 左下:束管监测 -->
-    <Module class="wide-module" :x="20" :y="732" :width="930" :height="326" title="束管监测">
+    <Module class="wide-module" :x="20" :y="649" :width="930" :height="260" title="束管监测">
       <div v-if="displayBundleRows.length" class="table-panel">
         <div class="data-table bundle-table">
           <div class="table-head">
@@ -118,7 +118,7 @@
     </Module>
 
     <!-- 右下:密闭监测 -->
-    <Module class="wide-module" :x="969" :y="732" :width="929" :height="326" title="密闭监测">
+    <Module class="wide-module" :x="969" :y="649" :width="929" :height="260" title="密闭监测">
       <div v-if="displayClosedRows.length" class="table-panel">
         <div class="data-table device-table">
           <div class="table-head">
@@ -158,7 +158,6 @@
   import FiberTemperatureChart from './FiberTemperatureChart.vue';
   import PanelSelect from './PanelSelect.vue';
   import { computed, nextTick, onUnmounted, ref, watch } from 'vue';
-  import { BUNDLE_MONITOR_ROWS, DEVICE_MONITOR_ROWS, FIBER_CHART_DATA, SENSOR_GROUPS } from '../data';
   import type { FiberChartData, SensorGroup } from '../data';
   import { getMonitorDeviceList } from '../monitorDevice.api';
   import { getSafetyEvaluationByScene } from '../safetyEvaluation.api';
@@ -231,109 +230,33 @@
     }
   }
 
-  const sceneSeed = computed(() => {
-    const key = `${props.manageSystemId || ''}|${props.sceneName || ''}`;
-    let hash = 0;
-    for (let i = 0; i < key.length; i++) {
-      hash = (hash * 31 + key.charCodeAt(i)) >>> 0;
-    }
-    return hash;
-  });
-
-  function rotate<T>(list: T[], offset: number): T[] {
-    if (!list.length) return list;
-    const start = offset % list.length;
-    return [...list.slice(start), ...list.slice(0, start)];
-  }
-
-  const fallbackSensorGroups = computed<SensorGroup[]>(() => rotate(SENSOR_GROUPS, sceneSeed.value % Math.max(1, SENSOR_GROUPS.length)));
-
-  const fallbackBundleRows = computed<BundleDisplayRow[]>(() => {
-    const rows = rotate(BUNDLE_MONITOR_ROWS, sceneSeed.value % Math.max(1, BUNDLE_MONITOR_ROWS.length));
-    return rows.map((row, index) => ({
-      deviceNo: row.deviceNo,
-      o2: (Number(row.o2) + ((sceneSeed.value + index) % 3) * 0.01).toFixed(2),
-      co: String(row.co),
-      co2: row.co2,
-      ch4: row.ch4,
-      c2h4: row.c2h4,
-      c2h2: row.c2h2,
-      temp: '--',
-    }));
-  });
-
-  const deviceRows = computed(() => {
-    const rows = rotate(DEVICE_MONITOR_ROWS, sceneSeed.value % Math.max(1, DEVICE_MONITOR_ROWS.length));
-    return rows.map((row, index) => ({
-      ...row,
-      temp: (Number(row.temp) + ((sceneSeed.value + index) % 3) * 0.1).toFixed(1),
-    }));
-  });
-
-  const fallbackFiberData = computed<FiberChartData>(() => {
-    const delta = (sceneSeed.value % 7) * 12;
-    return {
-      ...FIBER_CHART_DATA,
-      solid: FIBER_CHART_DATA.solid.map((value) => Math.min(1000, value + delta)),
-      dashed: FIBER_CHART_DATA.dashed.map((value) => Math.min(1000, value + delta)),
-    };
-  });
-
-  const fallbackClosedRows = computed<ClosedMonitorRow[]>(() =>
-    deviceRows.value.map((row) => ({
-      deviceNo: row.deviceNo,
-      o2: row.o2,
-      co: row.co,
-      co2: row.co2,
-      ch4: row.ch4,
-      c2h4: '--',
-      c2h2: '--',
-      temp: row.temp,
-    }))
-  );
-
-  const apiSensorGroups = ref<SensorGroup[] | null>(null);
-  const apiBundleRows = ref<BundleDisplayRow[] | null>(null);
-  const apiFiberSeries = ref<FiberSeriesOption[] | null>(null);
-  const apiClosedRows = ref<ClosedMonitorRow[] | null>(null);
+  const apiSensorGroups = ref<SensorGroup[]>([]);
+  const apiBundleRows = ref<BundleDisplayRow[]>([]);
+  const apiFiberSeries = ref<FiberSeriesOption[]>([]);
+  const apiClosedRows = ref<ClosedMonitorRow[]>([]);
   const selectedFiberId = ref('');
 
   const fiberOptions = computed(() =>
-    (apiFiberSeries.value || []).map((item) => ({
+    apiFiberSeries.value.map((item) => ({
       label: item.name,
       value: item.id,
       score: 0,
     }))
   );
 
-  const displaySensorGroups = computed(() => apiSensorGroups.value ?? fallbackSensorGroups.value);
-  const displayBundleRows = computed(() => apiBundleRows.value ?? fallbackBundleRows.value);
-  const displayFiberData = computed(() => {
+  const displaySensorGroups = computed(() => apiSensorGroups.value);
+  const displayBundleRows = computed(() => apiBundleRows.value);
+  const displayFiberData = computed<FiberChartData>(() => {
     const series = apiFiberSeries.value;
-    if (series !== null) {
-      if (!series.length) {
-        return { categories: [], solid: [], dashed: [], peakIndex: 0 } as FiberChartData;
-      }
-      return (series.find((item) => item.id === selectedFiberId.value) ?? series[0]).data;
-    }
-    return fallbackFiberData.value;
+    if (!series.length) return { categories: [], solid: [], dashed: [], peakIndex: 0 };
+    return (series.find((item) => item.id === selectedFiberId.value) ?? series[0]).data;
   });
-  const displayClosedRows = computed(() => apiClosedRows.value ?? fallbackClosedRows.value);
+  const displayClosedRows = computed(() => apiClosedRows.value);
   const selectedFiberName = computed(() => {
     const series = apiFiberSeries.value;
-    if (!series?.length) return '光纤测温';
+    if (!series.length) return '光纤测温';
     return (series.find((item) => item.id === selectedFiberId.value) ?? series[0]).name;
   });
-  const fiberStats = computed(() => {
-    const values = displayFiberData.value.solid.filter((value) => Number.isFinite(Number(value))).map(Number);
-    if (!values.length) return null;
-    const total = values.reduce((sum, value) => sum + value, 0);
-    return {
-      max: Math.max(...values).toFixed(1),
-      min: Math.min(...values).toFixed(1),
-      avg: (total / values.length).toFixed(1),
-    };
-  });
 
   let deviceTimer: number | undefined;
   let deviceRequestSeq = 0;
@@ -377,33 +300,25 @@
       });
   }
 
-  function buildSensorGroups(devices: any[]): SensorGroup[] {
-    const pick = (type: string) => devices.filter((device) => device?.deviceType === type);
-    const o2List = pick('modelsensor_o2');
-    const coList = pick('modelsensor_co');
-    const tempList = pick('modelsensor_temperature');
-    if (!o2List.length && !coList.length && !tempList.length) return [];
-
-    const maxLength = Math.min(2, Math.max(o2List.length, coList.length, tempList.length));
-    return Array.from({ length: maxLength }, (_, index) => {
-      const o2 = o2List[index];
-      const co = coList[index];
-      const temp = tempList[index];
-      const sourceName = (device: any) => device?.strname || device?.strinstallpos || '';
-      const rowLabel = (label: string, device: any) => {
-        const source = sourceName(device);
-        return source ? `${label} · ${source}` : label;
-      };
-
-      return {
-        name: `监测组#${index + 1}`,
+  /** 安全监控传感器(safetymonitor_normal):组标题取当前场景名称,行标题取设备安装位置 */
+  function buildSensorGroups(devices: any[], sceneName: string): SensorGroup[] {
+    const pick = (match: (read: any) => boolean) => devices.find((device) => match(device?.readData || {}));
+    const o2 = pick((read) => read.o2val !== undefined);
+    const ch4 = pick((read) => read.ch4val !== undefined || read.gasval !== undefined);
+    const temp = pick((read) => read.temperature !== undefined || read.temp !== undefined);
+    if (!o2 && !ch4 && !temp) return [];
+
+    const rowLabel = (device: any, fallback: string) => device?.strinstallpos || device?.strname || fallback;
+    return [
+      {
+        name: sceneName || '传感器监测',
         rows: [
-          { label: rowLabel('氧气', o2), value: withUnit(o2?.readData?.o2val, '%', 2) },
-          { label: rowLabel('一氧化碳', co), value: withUnit(co?.readData?.coval, 'ppm', 2) },
-          { label: rowLabel('温度', temp), value: withUnit(temp?.readData?.temperature, '℃', 1) },
+          { label: rowLabel(o2, '回风隅角氧气'), value: withUnit(o2?.readData?.o2val, '%', 2) },
+          { label: rowLabel(ch4, '回风巷甲烷'), value: withUnit(ch4?.readData?.gasval ?? ch4?.readData?.ch4val, '%', 2) },
+          { label: rowLabel(temp, '回风巷温度'), value: withUnit(temp?.readData?.temperature ?? temp?.readData?.temp, '℃', 1) },
         ],
-      };
-    });
+      },
+    ];
   }
 
   function buildFiberSeries(devices: any[]): FiberSeriesOption[] {
@@ -437,7 +352,6 @@
         id: String(device.deviceID ?? device.strname ?? `fiber-${deviceIndex}`),
         name: device.strname || device.strinstallpos || `光纤${deviceIndex + 1}`,
         data: {
-          ...FIBER_CHART_DATA,
           categories: validPoints.map((point) => `测点${point.pos}`),
           solid,
           dashed: [],
@@ -495,10 +409,10 @@
   }
 
   function resetMonitorDeviceData() {
+    // 密闭监测数据与场景无关,不随场景切换清空
     apiBundleRows.value = [];
     apiSensorGroups.value = [];
     apiFiberSeries.value = [];
-    apiClosedRows.value = [];
     selectedFiberId.value = '';
     resetScrollPositions();
   }
@@ -523,6 +437,14 @@
     }
   }
 
+  /** 密闭监测:数据与场景无关,只在进入页面和轮询时刷新 */
+  async function loadClosedMonitor() {
+    const devices = await loadClosedDevices();
+    if (devices.length) {
+      apiClosedRows.value = buildClosedRows(devices);
+    }
+  }
+
   async function loadMonitorDevices() {
     const systemID = props.manageSystemId;
     if (!systemID) return;
@@ -534,11 +456,7 @@
 
       const groups = getSceneGroups(res);
       apiBundleRows.value = buildBundleRows(collectGroupDevices(groups, 'bundletube'));
-      apiSensorGroups.value = buildSensorGroups(collectGroupDevices(groups, 'modelsensor'));
-
-      const closedDevices = await loadClosedDevices();
-      if (requestId !== deviceRequestSeq) return;
-      apiClosedRows.value = buildClosedRows(closedDevices.length ? closedDevices : collectGroupDevices(groups, 'obfurage'));
+      apiSensorGroups.value = buildSensorGroups(collectGroupDevices(groups, 'safetymonitor'), props.sceneName || '');
 
       const series = buildFiberSeries(collectGroupDevices(groups, 'fiber'));
       apiFiberSeries.value = series;
@@ -553,6 +471,7 @@
     deviceTimer = window.setInterval(() => {
       if (document.hidden) return;
       void loadMonitorDevices();
+      void loadClosedMonitor();
       void loadStageEvaluation();
     }, 60000);
   }
@@ -581,6 +500,7 @@
       if (active) {
         resetScrollPositions();
         void loadMonitorDevices();
+        void loadClosedMonitor();
         void loadStageEvaluation();
         startPolling();
       } else {
@@ -634,14 +554,14 @@
     flex-direction: column;
     align-items: center;
     height: 100%;
-    padding: 72px 4px 0px;
+    padding: 50px 4px 0;
     box-sizing: border-box;
   }
 
   .stage-emblem {
     position: absolute;
     left: 50%;
-    top: 22px;
+    top: 6px;
     z-index: 2;
     width: 110px;
     height: 46px;
@@ -672,8 +592,8 @@
     flex-direction: column;
     align-items: center;
     width: 347px;
-    height: 130px;
-    padding-top: 16px;
+    height: 122px;
+    padding-top: 12px;
     box-sizing: border-box;
     background: url('@/assets/images/vent/home/selfIgnition/2-2.png') no-repeat center / 100% 100%;
   }
@@ -688,15 +608,15 @@
   .stage-eval-button {
     position: absolute;
     left: 50%;
-    bottom: 16px;
+    bottom: 12px;
     width: 280px;
-    height: 70px;
+    height: 64px;
     margin: 0;
     padding: 0;
     border: none;
     background: url('@/assets/images/vent/home/selfIgnition/2-3.png') no-repeat center / 100% 100%;
     color: #fff;
-    font-size: 24px;
+    font-size: 22px;
     font-weight: 600;
     letter-spacing: 2px;
     cursor: pointer;
@@ -715,7 +635,10 @@
     width: 364px;
     min-height: 0;
     box-sizing: border-box;
+    overflow-x: hidden;
+    overflow-y: auto;
     background: url('@/assets/images/vent/home/selfIgnition/2-5.png') no-repeat center / 100% 100%;
+    .scrollbar-cyan();
   }
 
   .stage-warning {
@@ -723,33 +646,33 @@
     flex: none;
     align-items: flex-start;
     gap: 0;
-    min-height: 130px;
-    padding: 12px 4px 0 26px;
+    min-height: 108px;
+    padding: 8px 4px 0 24px;
     box-sizing: border-box;
   }
 
   .stage-warning-icon {
     position: relative;
     flex: none;
-    width: 107px;
-    height: 109px;
+    width: 92px;
+    height: 94px;
   }
 
   .stage-warning-pedestal {
     position: absolute;
     left: 0;
     bottom: 0;
-    width: 107px;
-    height: 109px;
+    width: 92px;
+    height: 94px;
     filter: drop-shadow(0 0 10px rgba(61, 246, 255, 0.35));
   }
 
   .stage-warning-bolt {
     position: absolute;
     left: 50%;
-    top: 10px;
-    width: 52px;
-    height: 52px;
+    top: 14px;
+    width: 44px;
+    height: 44px;
     transform: translateX(-50%);
     filter: drop-shadow(0 0 8px rgba(61, 246, 255, 0.65));
   }
@@ -758,33 +681,33 @@
     display: flex;
     flex-direction: column;
     min-width: 0;
-    margin-top: 12px;
+    margin-top: 16px;
     margin-left: 4px;
   }
 
   .stage-warning-title {
     color: #fff;
-    font-size: 17px;
+    font-size: 15px;
     font-weight: 600;
     letter-spacing: 0.5px;
     white-space: nowrap;
   }
 
   .stage-warning-level {
-    margin-top: 22px;
-    font-size: 20px;
-    font-weight: 800;
-    line-height: 26px;
+    margin-top: 14px;
+    font-size: 18px;
+    line-height: 22px;
     letter-spacing: 1px;
+    font-family: 'douyuFont';
   }
 
   .stage-advice {
     position: relative;
     flex: none;
     width: 280px;
-    height: 130px;
+    height: 110px;
     min-height: 0;
-    margin: 9px auto 0;
+    margin: 6px auto 0;
     box-sizing: border-box;
     border: 1px solid rgba(61, 246, 255, 0.55);
     background: url('@/assets/images/vent/home/selfIgnition/2-6.png') no-repeat center / 100% 100%;
@@ -808,13 +731,13 @@
     left: -1px;
     display: flex;
     align-items: center;
-    width: 146px;
-    height: 24px;
-    padding-left: 12px;
+    width: 132px;
+    height: 22px;
+    padding-left: 10px;
     box-sizing: border-box;
     background: url('@/assets/images/vent/home/selfIgnition/2-7.png') no-repeat center / 100% 100%;
     color: #fff;
-    font-size: 16px;
+    font-size: 14px;
     font-weight: 600;
     letter-spacing: 0.5px;
   }
@@ -824,9 +747,9 @@
     position: absolute;
     left: 0;
     right: 0;
-    top: 28px;
+    top: 26px;
     bottom: 0;
-    padding: 6px 10px 8px 38px;
+    padding: 4px 8px 6px 34px;
     box-sizing: border-box;
     overflow-x: hidden;
     overflow-y: auto;
@@ -835,18 +758,18 @@
     p {
       margin: 0;
       color: #fff;
-      font-size: 17px;
-      line-height: 26px;
+      font-size: 15px;
+      line-height: 22px;
       letter-spacing: 0.3px;
     }
   }
 
   .stage-advice-icon {
     position: absolute;
-    left: 14px;
-    top: 10px;
-    width: 14px;
-    height: 14px;
+    left: 12px;
+    top: 8px;
+    width: 12px;
+    height: 12px;
     border-radius: 50%;
     background: #e8362f;
     box-shadow: 0 0 10px rgba(232, 54, 47, 0.85);
@@ -960,11 +883,13 @@
 
   .sensor-group-title {
     position: relative;
-    display: flex;
+    display: inline-flex;
     align-items: center;
-    width: 128px;
+    width: auto;
+    min-width: 128px;
+    max-width: 100%;
     height: 27px;
-    padding-left: 15px;
+    padding: 0 22px 0 15px;
     box-sizing: border-box;
     background: url('@/assets/images/vent/home/selfIgnition/3-1.png') no-repeat center / 100% 100%;
     color: #3df6ff;
@@ -972,6 +897,9 @@
     font-weight: 700;
     line-height: 27px;
     letter-spacing: 1px;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
     text-shadow: 0 0 8px rgba(61, 246, 255, 0.45);
   }
 

+ 149 - 43
src/views/vent/home/selfIgnition/components/OverviewView.vue

@@ -1,21 +1,25 @@
 <template>
   <div class="ignition-view overview-view">
     <!-- 左:矿井采空区概览 -->
-    <Module class="overview-module" :x="20" :y="114" :width="393" :height="576" title="矿井采空区概览">
-      <div class="overview-panel">
-        <div v-for="item in overview" :key="item.label" class="goaf-item">
+    <Module class="overview-module" :x="20" :y="98" :width="393" :height="495" title="矿井采空区概览">
+      <div v-if="overview.length" class="overview-panel">
+        <div v-for="(item, index) in overview" :key="item.label" class="goaf-item">
           <span class="goaf-icon">
-            <img src="@/assets/images/vent/home/selfIgnition/goaf-icon.svg" alt="" />
+            <img :src="goafIcon(item.label, index)" alt="" />
           </span>
           <span class="goaf-label">{{ item.label }}:</span>
           <span class="goaf-value">{{ item.value }}</span>
         </div>
       </div>
+      <div v-else class="module-empty">
+        <img src="@/assets/images/vent/no-data.png" alt="暂无数据" />
+        <span>暂无数据</span>
+      </div>
     </Module>
 
     <!-- 左下:安装设备情况 -->
-    <Module class="install-module" :x="20" :y="722" :width="393" :height="336" title="安装设备情况">
-      <div class="install-panel">
+    <Module class="install-module" :x="20" :y="620" :width="393" :height="289" title="安装设备情况">
+      <div v-if="devices.length" class="install-panel">
         <div
           v-for="(device, index) in devices"
           :key="`${device.name}-${index}`"
@@ -36,11 +40,15 @@
           >
         </div>
       </div>
+      <div v-else class="module-empty">
+        <img src="@/assets/images/vent/no-data.png" alt="暂无数据" />
+        <span>暂无数据</span>
+      </div>
     </Module>
 
     <!-- 右下:分级预警表 -->
-    <Module class="table-module" :x="433" :y="722" :width="1465" :height="336" title="矿井采空区分级预警">
-      <div class="warning-table-panel">
+    <Module class="table-module" :x="433" :y="620" :width="1465" :height="289" title="矿井采空区分级预警">
+      <div v-if="warnings.length" class="warning-table-panel">
         <div class="warning-table">
           <div class="table-head">
             <span class="col-index">序号</span>
@@ -50,16 +58,24 @@
             <span class="col-safety">安全评价等级</span>
           </div>
           <div class="table-body">
-            <div v-for="row in warnings" :key="row.id" class="table-row">
+            <div
+              v-for="row in warnings"
+              :key="row.id"
+              class="table-row"
+              :class="{ 'table-row-alert': !!warnRowRgb(row.level) }"
+              :style="warnRowRgb(row.level) ? { '--warn-rgb': warnRowRgb(row.level) } : undefined"
+            >
               <span class="col-index">{{ row.id }}</span>
               <span class="col-name">{{ row.name }}</span>
               <span class="col-seam">{{ row.seam }}</span>
               <span class="col-level level-cell">
-                <img v-if="row.level && row.level !== '未预警'" class="level-icon warning-icon" :src="warningLevelIcon" alt="" />
+                <img v-if="isHighLevel(row.level)" class="level-icon warning-icon" :src="warningLevelIcon" alt="" />
+                <img v-else-if="isMidLevel(row.level)" class="level-icon warning-icon" :src="warningLevelOrangeIcon" alt="" />
                 <span :title="row.level">{{ row.level }}</span>
               </span>
               <span class="col-safety level-cell">
-                <img v-if="showSafetyIcon(row.safetyLevel || row.level)" class="level-icon safety-icon" :src="safetyLevelIcon" alt="" />
+                <img v-if="isHighLevel(row.safetyLevel || row.level)" class="level-icon safety-icon" :src="safetyLevelIcon" alt="" />
+                <img v-else-if="isMidLevel(row.safetyLevel || row.level)" class="level-icon safety-icon" :src="safetyLevelOrangeIcon" alt="" />
                 <span :title="row.safetyLevel || row.level">{{ row.safetyLevel || row.level }}</span>
               </span>
             </div>
@@ -67,6 +83,10 @@
           </div>
         </div>
       </div>
+      <div v-else class="module-empty">
+        <img src="@/assets/images/vent/no-data.png" alt="暂无数据" />
+        <span>暂无数据</span>
+      </div>
     </Module>
   </div>
 </template>
@@ -80,6 +100,26 @@
   import sealedMonitorIcon from '@/assets/images/vent/home/selfIgnition/install-sealed-monitor.svg';
   import warningLevelIcon from '@/assets/images/vent/home/selfIgnition/level-warning.svg';
   import safetyLevelIcon from '@/assets/images/vent/home/selfIgnition/level-safety.svg';
+  import warningLevelOrangeIcon from '@/assets/images/vent/home/selfIgnition/level-warning-orange.svg';
+  import safetyLevelOrangeIcon from '@/assets/images/vent/home/selfIgnition/level-safety-orange.svg';
+  import mineGoafIcon from '@/assets/images/vent/home/selfIgnition/goaf-stat-total.svg';
+  import closedGoafIcon from '@/assets/images/vent/home/selfIgnition/goaf-stat-closed.svg';
+  import withdrawGoafIcon from '@/assets/images/vent/home/selfIgnition/goaf-stat-withdraw.svg';
+  import miningGoafIcon from '@/assets/images/vent/home/selfIgnition/goaf-stat-mining.svg';
+  import stoppedGoafIcon from '@/assets/images/vent/home/selfIgnition/goaf-stat-stopped.svg';
+
+  const GOAF_ICONS: Record<string, string> = {
+    矿井采空区总数: mineGoafIcon,
+    已封闭采空区数: closedGoafIcon,
+    回撤工作面采空区数: withdrawGoafIcon,
+    回采工作面采空区数: miningGoafIcon,
+    停产工作面采空区数: stoppedGoafIcon,
+  };
+  const GOAF_ICON_LIST = [mineGoafIcon, closedGoafIcon, withdrawGoafIcon, miningGoafIcon, stoppedGoafIcon];
+
+  function goafIcon(label: string, index: number) {
+    return GOAF_ICONS[label] || GOAF_ICON_LIST[index] || mineGoafIcon;
+  }
 
   const props = defineProps<{
     overview: GoafOverviewItem[];
@@ -97,8 +137,20 @@
     return DEVICE_ICONS[name] || '';
   }
 
-  function showSafetyIcon(level: string | undefined) {
-    return !!level && level !== '安全' && level !== '未评价';
+  function isHighLevel(level: string | undefined) {
+    return !!level && level.includes('高风险');
+  }
+
+  function isMidLevel(level: string | undefined) {
+    return !!level && /中(等)?风险/.test(level);
+  }
+
+  /** 整行预警框颜色:与预警图标一致,只有高风险(红)、中风险(橙)显示 */
+  function warnRowRgb(level: string | undefined) {
+    if (!level) return '';
+    if (level.includes('高风险')) return '255, 77, 79';
+    if (/中(等)?风险/.test(level)) return '255, 157, 28';
+    return '';
   }
 
   // 表体固定 5 行视口,数据不足时用空行补足;超过 5 行时在表体内部滚动
@@ -113,71 +165,110 @@
     inset: 0;
   }
 
+  .module-empty {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    gap: 8px;
+    width: 100%;
+    height: 100%;
+    padding: 8px;
+    box-sizing: border-box;
+
+    img {
+      max-width: 70%;
+      max-height: 80%;
+      object-fit: contain;
+    }
+
+    span {
+      color: #8fc7e8;
+      font-size: 13px;
+      letter-spacing: 1px;
+    }
+  }
+
   .overview-panel {
     display: flex;
     flex-direction: column;
-    justify-content: space-evenly;
-    gap: 24px;
+    gap: 31px;
     height: 100%;
-    padding: 0px 10px 0px 20px;
+    padding: 31px 23px 2px;
     box-sizing: border-box;
-    overflow-x: hidden;
-    overflow-y: auto;
-    scrollbar-gutter: stable;
-    .scrollbar-cyan();
+    overflow: hidden;
   }
 
   .goaf-item {
-    position: relative;
     display: flex;
-    align-items: center;
     flex: none;
-    height: 48px;
-    padding: 0 14px 0 60px;
+    align-items: center;
+    height: 52px;
+    padding: 0 15px 0 2px;
     box-sizing: border-box;
-    border: none;
+    border: 1px solid #259bdc;
     border-radius: 5px;
-    overflow: hidden;
-    background-color: #072b49;
-    background-image: url('@/assets/images/vent/home/selfIgnition/card-bg.png');
-    background-repeat: no-repeat;
-    background-size: 100% 100%;
+    background: linear-gradient(90deg, #092b48 0%, #0d496f 100%);
+    box-shadow: 0 0 8px rgba(37, 155, 220, 0.18), inset 0 0 14px rgba(37, 155, 220, 0.12);
   }
 
   .goaf-icon {
-    position: absolute;
-    left: 2px;
-    width: 50px;
-    height: 50px;
-    background: url('@/assets/images/vent/home/selfIgnition/list-icon-bg.png') no-repeat center / 100% 100%;
+    position: relative;
     display: flex;
+    flex: none;
     align-items: center;
     justify-content: center;
+    width: 45px;
+    height: 45px;
+    box-sizing: border-box;
+    border: 2px solid transparent;
+    border-radius: 50%;
+    background: linear-gradient(180deg, #3df6ff 0%, #2fc3d8 100%) border-box;
+    box-shadow: 0 0 10px rgba(61, 246, 255, 0.5);
+
+    // 圆环内侧深色底
+    &::before {
+      content: '';
+      position: absolute;
+      inset: 2px;
+      border-radius: 50%;
+      background: radial-gradient(circle at 50% 35%, #16587f 0%, #0a2f4d 78%);
+    }
 
     img {
-      width: 20px;
-      height: 15px;
+      position: relative;
+      z-index: 1;
+      width: auto;
+      max-width: 26px;
+      height: auto;
+      max-height: 22px;
     }
   }
 
   .goaf-label {
     flex: 1;
+    min-width: 0;
+    margin-left: 18px;
+    overflow: hidden;
     color: #fff;
-    font-size: 16px;
+    font-size: 19px;
     font-weight: 600;
-    letter-spacing: 0;
+    letter-spacing: 0.5px;
+    white-space: nowrap;
+    text-overflow: ellipsis;
   }
 
   .goaf-value {
-    display: inline-block;
-    color: #eaffff;
+    flex: none;
+    margin-left: 8px;
+    color: #fff;
     font-family: Arial, sans-serif;
     font-size: 19px;
     font-weight: 800;
     font-style: italic;
     line-height: 1;
     letter-spacing: 1px;
-    transform: scaleX(1.2);
+    transform: scaleX(1.15);
     transform-origin: right center;
   }
 
@@ -201,7 +292,7 @@
     display: flex;
     align-items: center;
     flex: none;
-    height: 69px;
+    height: 48px;
     padding: 0 20px 0 12px;
     box-sizing: border-box;
 
@@ -321,6 +412,8 @@
   }
 
   .table-row {
+    position: relative;
+    z-index: 0;
     height: 42px;
     box-sizing: border-box;
     color: #fff;
@@ -331,6 +424,19 @@
     &:nth-child(even) {
       background: #0d4167;
     }
+
+    // 按预警等级着色的整行预警框
+    &.table-row-alert::before {
+      content: '';
+      position: absolute;
+      z-index: -1;
+      inset: 2px;
+      border: 1px solid rgba(var(--warn-rgb), 0.95);
+      border-radius: 6px;
+      background: linear-gradient(180deg, rgba(var(--warn-rgb), 0.2), rgba(var(--warn-rgb), 0.04) 50%, rgba(var(--warn-rgb), 0.18));
+      box-shadow: 0 0 10px rgba(var(--warn-rgb), 0.45), inset 0 0 14px rgba(var(--warn-rgb), 0.3);
+      pointer-events: none;
+    }
   }
 
   .table-row-empty {

+ 1 - 2
src/views/vent/home/selfIgnition/components/PanelSelect.vue

@@ -185,9 +185,8 @@
     height: 34px;
     padding: 0 28px 0 10px;
     box-sizing: border-box;
-    border: 1px solid rgba(61, 246, 255, 0.42);
+    border: 1px solid #0199ea;
     border-radius: 4px;
-    background: url('@/assets/images/vent/home/selfIgnition/card-bg.png') no-repeat center / 100% 100%;
     color: #fff;
     font-size: 14px;
     cursor: pointer;

+ 1 - 514
src/views/vent/home/selfIgnition/data.ts

@@ -1,8 +1,5 @@
 /**
- * 张家峁煤自燃监测预警页面数据
- *
- * 当前阶段后端接口尚未提供,页面先使用本地模拟数据,
- * 后续接入接口时只需要替换本文件中的模拟常量即可。
+ * 张家峁煤自燃监测预警页面公共类型
  */
 
 export interface GoafOverviewItem {
@@ -16,14 +13,6 @@ export interface DeviceInstallItem {
   running: number;
 }
 
-export interface OverallWarning {
-  level: number;
-  levelText: string;
-  levelName: string;
-  total: number;
-  color: string;
-}
-
 export interface WarningRow {
   id: number;
   name: string;
@@ -33,430 +22,12 @@ export interface WarningRow {
   status?: string;
 }
 
-export interface AlertItem {
-  id: number;
-  time: string;
-  level: number;
-  location: string;
-  message: string;
-}
-
-export interface BundleRow {
-  point: string;
-  o2: string;
-  co: number;
-  ch4: string;
-  c2h4: string;
-  temp: number;
-  status: '正常' | '关注' | '预警';
-}
-
-export interface FiberTrend {
-  times: string[];
-  maxTemp: number[];
-  avgTemp: number[];
-  maxValue: number;
-  avgValue: number;
-  pointCount: number;
-}
-
-export interface RiskLevel {
-  level: number;
-  name: string;
-  range: string;
-  colorName: string;
-  color: string;
-}
-
 export interface ManualOption {
   label: string;
   value: string;
   score: number;
 }
 
-export interface ManualField {
-  key: string;
-  label: string;
-  value: string;
-  options: ManualOption[];
-}
-
-export interface ManualGroup {
-  key: string;
-  title: string;
-  fields: ManualField[];
-}
-
-export interface EvaluationResult {
-  score: number;
-  level: number;
-  levelText: string;
-  color: string;
-  highlightLevel: number;
-  target: string;
-  time: string;
-  source: string;
-  suggestion: string;
-}
-
-export const GOAF_OVERVIEW: GoafOverviewItem[] = [
-  { label: '矿井采空区总数', value: 28 },
-  { label: '已封闭采空区数', value: 6 },
-  { label: '回撤工作面采空区数', value: 4 },
-  { label: '回采工作面采空区数', value: 12 },
-  { label: '停产工作面采空区数', value: 6 },
-];
-
-export const INSTALLED_DEVICES: DeviceInstallItem[] = [
-  { name: '束管监测', installed: 15, running: 13 },
-  { name: '光纤测温', installed: 15, running: 13 },
-  { name: '密闭监测', installed: 15, running: 13 },
-];
-
-export const OVERALL_WARNING: OverallWarning = {
-  level: 4,
-  levelText: 'IV',
-  levelName: '高风险',
-  total: 12,
-  color: '#ff9d1c',
-};
-
-export const WARNING_ROWS: WarningRow[] = [
-  { id: 1, name: '12采空区', seam: '5-2煤', level: '一般风险', status: '回采中' },
-  { id: 2, name: '14采空区', seam: '5-2煤', level: '一般风险', status: '回撤中' },
-  { id: 3, name: '16采空区', seam: '5-1煤', level: '一般风险', status: '停产' },
-  { id: 4, name: '18采空区', seam: '5-2煤', level: '低风险', status: '回采中' },
-  { id: 5, name: '20采空区', seam: '5-1煤', level: '中等风险', status: '回采中' },
-  { id: 6, name: '22采空区', seam: '5-2煤', level: '低风险', status: '已封闭' },
-  { id: 7, name: '24采空区', seam: '4-2煤', level: '一般风险', status: '回采中' },
-  { id: 8, name: '26采空区', seam: '4-2煤', level: '低风险', status: '已封闭' },
-  { id: 9, name: '28采空区', seam: '5-1煤', level: '中等风险', status: '回撤中' },
-  { id: 10, name: '30采空区', seam: '5-2煤', level: '一般风险', status: '停产' },
-  { id: 11, name: '32采空区', seam: '4-2煤', level: '低风险', status: '已封闭' },
-  { id: 12, name: '34采空区', seam: '5-1煤', level: '一般风险', status: '回采中' },
-];
-
-export const ALERTS: AlertItem[] = [
-  { id: 1, time: '09:28:16', level: 4, location: '12采空区', message: '束管测点 CO 浓度上升至 24ppm' },
-  { id: 2, time: '09:16:42', level: 3, location: '20采空区', message: '密闭内 O₂ 浓度低于 15%,请关注' },
-  { id: 3, time: '08:57:03', level: 2, location: '14采空区', message: '光纤测温 3# 测点温度波动 1.8℃' },
-  { id: 4, time: '08:35:27', level: 4, location: '28采空区', message: '回风顺槽 CH₄ 浓度达到 0.86%' },
-  { id: 5, time: '08:12:51', level: 2, location: '18采空区', message: '风速传感器数据短时中断,已恢复' },
-];
-
-export const BUNDLE_ROWS: BundleRow[] = [
-  { point: '12采空区-1#', o2: '18.62', co: 16, ch4: '0.42', c2h4: '0.00', temp: 26.4, status: '正常' },
-  { point: '12采空区-2#', o2: '17.85', co: 24, ch4: '0.56', c2h4: '0.02', temp: 28.1, status: '关注' },
-  { point: '14采空区-1#', o2: '19.04', co: 9, ch4: '0.35', c2h4: '0.00', temp: 25.2, status: '正常' },
-  { point: '16采空区-1#', o2: '16.92', co: 31, ch4: '0.63', c2h4: '0.04', temp: 30.6, status: '预警' },
-  { point: '20采空区-1#', o2: '18.11', co: 18, ch4: '0.48', c2h4: '0.01', temp: 27.3, status: '正常' },
-  { point: '28采空区-1#', o2: '17.36', co: 27, ch4: '0.74', c2h4: '0.03', temp: 29.4, status: '关注' },
-];
-
-export const FIBER_TREND: FiberTrend = {
-  times: [
-    '00:00',
-    '01:00',
-    '02:00',
-    '03:00',
-    '04:00',
-    '05:00',
-    '06:00',
-    '07:00',
-    '08:00',
-    '09:00',
-    '10:00',
-    '11:00',
-    '12:00',
-    '13:00',
-    '14:00',
-    '15:00',
-    '16:00',
-    '17:00',
-    '18:00',
-    '19:00',
-    '20:00',
-    '21:00',
-    '22:00',
-    '23:00',
-  ],
-  maxTemp: [
-    24.1, 23.8, 23.6, 23.4, 23.5, 24.0, 25.2, 26.8, 28.4, 30.1, 31.6, 32.6, 33.1, 32.8, 32.2, 31.5, 30.6, 29.4, 28.2, 27.3, 26.6, 26.0, 25.4, 24.8,
-  ],
-  avgTemp: [
-    22.2, 22.0, 21.9, 21.8, 21.9, 22.1, 22.6, 23.2, 23.9, 24.5, 25.1, 25.6, 25.9, 25.8, 25.6, 25.3, 24.9, 24.5, 24.1, 23.8, 23.4, 23.1, 22.8, 22.5,
-  ],
-  maxValue: 33.1,
-  avgValue: 23.9,
-  pointCount: 15,
-};
-
-export const RISK_LEVELS: RiskLevel[] = [
-  { level: 1, name: 'I 低风险', range: '0-20', colorName: '绿色', color: '#7ed321' },
-  { level: 2, name: 'II 较低风险', range: '20-40', colorName: '蓝色', color: '#3df6ff' },
-  { level: 3, name: 'III 中等风险', range: '40-60', colorName: '黄色', color: '#ffd15c' },
-  { level: 4, name: 'IV 高风险', range: '60-80', colorName: '橙色', color: '#ff9d1c' },
-  { level: 5, name: 'V 极高风险', range: '80-100', colorName: '红色', color: '#ff4d4f' },
-];
-
-export const MANUAL_GROUPS: ManualGroup[] = [
-  {
-    key: 'pre',
-    title: '采前评价',
-    fields: [
-      {
-        key: 'spontaneous',
-        label: '自燃倾向性',
-        value: '自燃',
-        options: [
-          { label: '不易自燃', value: '不易自燃', score: 3 },
-          { label: '自燃', value: '自燃', score: 10 },
-          { label: '容易自燃', value: '容易自燃', score: 18 },
-        ],
-      },
-      {
-        key: 'sealQuality',
-        label: '封闭质量',
-        value: '一般',
-        options: [
-          { label: '好', value: '好', score: 2 },
-          { label: '一般', value: '一般', score: 8 },
-          { label: '差', value: '差', score: 15 },
-        ],
-      },
-      {
-        key: 'residualCoal',
-        label: '遗煤厚度(m)',
-        value: '1.0',
-        options: [
-          { label: '0.5', value: '0.5', score: 3 },
-          { label: '1.0', value: '1.0', score: 7 },
-          { label: '1.5', value: '1.5', score: 11 },
-          { label: '2.0', value: '2.0', score: 15 },
-        ],
-      },
-      {
-        key: 'advanceSpeed',
-        label: '推进速度(m/d)',
-        value: '3.5',
-        options: [
-          { label: '4.8', value: '4.8', score: 3 },
-          { label: '3.5', value: '3.5', score: 7 },
-          { label: '2.5', value: '2.5', score: 11 },
-          { label: '1.5', value: '1.5', score: 15 },
-        ],
-      },
-      {
-        key: 'airLeakage',
-        label: '漏风强度',
-        value: '中',
-        options: [
-          { label: '低', value: '低', score: 3 },
-          { label: '中', value: '中', score: 8 },
-          { label: '高', value: '高', score: 15 },
-        ],
-      },
-    ],
-  },
-  {
-    key: 'condition',
-    title: '开采条件',
-    fields: [
-      {
-        key: 'roof',
-        label: '顶板岩性',
-        value: '泥岩',
-        options: [
-          { label: '砂岩', value: '砂岩', score: 3 },
-          { label: '泥岩', value: '泥岩', score: 8 },
-          { label: '复合顶板', value: '复合顶板', score: 12 },
-        ],
-      },
-      {
-        key: 'structure',
-        label: '地质构造',
-        value: '较复杂',
-        options: [
-          { label: '简单', value: '简单', score: 3 },
-          { label: '较复杂', value: '较复杂', score: 8 },
-          { label: '复杂', value: '复杂', score: 12 },
-        ],
-      },
-      {
-        key: 'miningMethod',
-        label: '采煤方法',
-        value: '综放',
-        options: [
-          { label: '综采', value: '综采', score: 4 },
-          { label: '综放', value: '综放', score: 10 },
-        ],
-      },
-      {
-        key: 'ventMode',
-        label: '通风方式',
-        value: 'U型',
-        options: [
-          { label: 'U型', value: 'U型', score: 4 },
-          { label: 'W型', value: 'W型', score: 8 },
-          { label: 'U+L型', value: 'U+L型', score: 10 },
-        ],
-      },
-      {
-        key: 'sealMode',
-        label: '封闭方式',
-        value: '永久密闭',
-        options: [
-          { label: '永久密闭', value: '永久密闭', score: 3 },
-          { label: '临时密闭', value: '临时密闭', score: 8 },
-          { label: '未封闭', value: '未封闭', score: 13 },
-        ],
-      },
-    ],
-  },
-  {
-    key: 'monitor',
-    title: '监测数据',
-    fields: [
-      {
-        key: 'o2',
-        label: 'O₂浓度(%)',
-        value: '15-18',
-        options: [
-          { label: '≥18', value: '≥18', score: 3 },
-          { label: '15-18', value: '15-18', score: 7 },
-          { label: '10-15', value: '10-15', score: 12 },
-          { label: '<10', value: '<10', score: 16 },
-        ],
-      },
-      {
-        key: 'co',
-        label: 'CO浓度(ppm)',
-        value: '10-24',
-        options: [
-          { label: '<10', value: '<10', score: 3 },
-          { label: '10-24', value: '10-24', score: 7 },
-          { label: '24-50', value: '24-50', score: 12 },
-          { label: '>50', value: '>50', score: 16 },
-        ],
-      },
-      {
-        key: 'ch4',
-        label: 'CH₄浓度(%)',
-        value: '0.5-1.0',
-        options: [
-          { label: '<0.5', value: '<0.5', score: 3 },
-          { label: '0.5-1.0', value: '0.5-1.0', score: 6 },
-          { label: '>1.0', value: '>1.0', score: 10 },
-        ],
-      },
-      {
-        key: 'temperature',
-        label: '温度(℃)',
-        value: '26-30',
-        options: [
-          { label: '<26', value: '<26', score: 3 },
-          { label: '26-30', value: '26-30', score: 7 },
-          { label: '30-35', value: '30-35', score: 12 },
-          { label: '>35', value: '>35', score: 16 },
-        ],
-      },
-    ],
-  },
-];
-
-export const SUGGESTIONS: Record<number, string> = {
-  1: '保持现有监测频次,按计划开展日常巡检,关注束管测点气体变化趋势。',
-  2: '关注束管测点变化趋势,定期校验传感器,保持采空区密闭完好。',
-  3: '加密束管采样频次,加强回风顺槽气体分析;对高温测点进行连续测温跟踪;必要时调整推进速度并落实注浆与注氮措施。',
-  4: '立即加密监测并核查高温测点,落实注浆、注氮等综合防灭火措施,必要时调整推进速度。',
-  5: '立即停止作业并撤出受影响区域人员,启动应急预案,实施连续监测与注浆注氮措施。',
-};
-
-const LEVEL_TEXT: Record<number, string> = {
-  1: 'I 低风险',
-  2: 'II 较低风险',
-  3: 'III 中等风险',
-  4: 'IV 高风险',
-  5: 'V 极高风险',
-};
-
-export const INITIAL_EVALUATION: EvaluationResult = {
-  score: 58.6,
-  level: 3,
-  levelText: 'III 高风险',
-  color: '#ff9d1c',
-  highlightLevel: 4,
-  target: '12采空区工作面',
-  time: '2026-10-12 09:30',
-  source: '人工录入',
-  suggestion: SUGGESTIONS[3],
-};
-
-/** 按 0-20 / 20-40 / 40-60 / 60-80 / 80-100 划分风险等级 */
-export function getRiskLevel(score: number): { level: number; name: string; color: string } {
-  if (score < 20) return { level: 1, name: LEVEL_TEXT[1], color: RISK_LEVELS[0].color };
-  if (score < 40) return { level: 2, name: LEVEL_TEXT[2], color: RISK_LEVELS[1].color };
-  if (score < 60) return { level: 3, name: LEVEL_TEXT[3], color: RISK_LEVELS[2].color };
-  if (score < 80) return { level: 4, name: LEVEL_TEXT[4], color: RISK_LEVELS[3].color };
-  return { level: 5, name: LEVEL_TEXT[5], color: RISK_LEVELS[4].color };
-}
-
-/** 根据人工录入的各项得分计算 0-100 的风险分值 */
-export function calcManualScore(groups: ManualGroup[]): number {
-  let score = 0;
-  let maxScore = 0;
-  groups.forEach((group) => {
-    group.fields.forEach((field) => {
-      const selected = field.options.find((option) => option.value === field.value);
-      score += selected?.score ?? 0;
-      maxScore += Math.max(...field.options.map((option) => option.score));
-    });
-  });
-  if (!maxScore) return 0;
-  return Math.round((score / maxScore) * 1000) / 10;
-}
-
-/** 深度复制人工录入表单,避免多个标签页共享同一份可变数据 */
-export function createManualGroups(): ManualGroup[] {
-  return MANUAL_GROUPS.map((group) => ({
-    ...group,
-    fields: group.fields.map((field) => ({
-      ...field,
-      options: field.options.map((option) => ({ ...option })),
-    })),
-  }));
-}
-
-export interface SelfIgnitionPageData {
-  overview: GoafOverviewItem[];
-  devices: DeviceInstallItem[];
-  overall: OverallWarning;
-  warnings: WarningRow[];
-  alerts: AlertItem[];
-  bundleRows: BundleRow[];
-  fiber: FiberTrend;
-}
-
-/** 生成页面数据副本;数据接口就绪后替换此函数即可 */
-export function createSelfIgnitionData(): SelfIgnitionPageData {
-  return {
-    overview: GOAF_OVERVIEW.map((item) => ({ ...item })),
-    devices: INSTALLED_DEVICES.map((item) => ({ ...item })),
-    overall: { ...OVERALL_WARNING },
-    warnings: WARNING_ROWS.map((item) => ({ ...item })),
-    alerts: ALERTS.map((item) => ({ ...item })),
-    bundleRows: BUNDLE_ROWS.map((item) => ({ ...item })),
-    fiber: {
-      ...FIBER_TREND,
-      times: [...FIBER_TREND.times],
-      maxTemp: [...FIBER_TREND.maxTemp],
-      avgTemp: [...FIBER_TREND.avgTemp],
-    },
-  };
-}
-
-/* ==================== 设备实时监测与分析 ==================== */
-
 export interface SensorReading {
   label: string;
   value: string;
@@ -467,93 +38,9 @@ export interface SensorGroup {
   rows: SensorReading[];
 }
 
-export const SENSOR_GROUPS: SensorGroup[] = [
-  {
-    name: '工作面#1',
-    rows: [
-      { label: '回风隅角氧气', value: '20.9%' },
-      { label: '回风巷一氧化碳', value: '12ppm' },
-      { label: '回风巷温度', value: '26.5℃' },
-    ],
-  },
-  {
-    name: '工作面#2',
-    rows: [
-      { label: '回风隅角氧气', value: '20.8%' },
-      { label: '回风巷一氧化碳', value: '15ppm' },
-      { label: '回风巷温度', value: '27.1℃' },
-    ],
-  },
-];
-
-export const NATURAL_FIRE_STAGE = {
-  levelText: 'IV',
-  levelName: '高风险',
-  color: '#ff9d1c',
-};
-
-export const ALERT_ADVICE = '加密束管采样频次,加强回风顺槽气体分析;对高温测点进行连续测温跟踪;必要时调整推进速度并落实注浆与注氮措施。';
-
 export interface FiberChartData {
   categories: string[];
   solid: number[];
   dashed: number[];
   peakIndex: number;
 }
-
-export const FIBER_CHART_DATA: FiberChartData = {
-  categories: ['测点01', '测点02', '测点03', '测点04', '测点05', '测点06', '测点07', '测点08', '测点09', '测点10', '测点11', '测点12'],
-  solid: [120, 180, 140, 160, 110, 140, 130, 210, 800, 520, 360, 280],
-  dashed: [160, 200, 170, 190, 140, 170, 150, 240, 700, 480, 320, 260],
-  peakIndex: 8,
-};
-
-export interface BundleMonitorRow {
-  deviceNo: string;
-  o2: string;
-  n2: string;
-  co: number;
-  co2: string;
-  ch4: string;
-  c2h4: string;
-  c2h6: string;
-  c2h2: string;
-}
-
-const BUNDLE_DEVICE_NAMES = ['1#束管', '2#束管', '3#束管', '4#束管'];
-
-export const BUNDLE_MONITOR_ROWS: BundleMonitorRow[] = Array.from({ length: 40 }, (_, index) => {
-  return {
-    deviceNo: BUNDLE_DEVICE_NAMES[index % 4],
-    o2: (20.9 - (index % 12) * 0.08).toFixed(2),
-    n2: (78.1 + (index % 9) * 0.06).toFixed(2),
-    co: 6 + (index % 15) * 2,
-    co2: (0.03 + (index % 10) * 0.005).toFixed(3),
-    ch4: (0.18 + (index % 8) * 0.03).toFixed(2),
-    c2h4: (index % 5 === 0 ? 0.02 : 0).toFixed(2),
-    c2h6: (index % 6 === 0 ? 0.01 : 0).toFixed(2),
-    c2h2: (index % 7 === 0 ? 0.01 : 0).toFixed(2),
-  };
-});
-
-export interface DeviceMonitorRow {
-  deviceNo: string;
-  o2: string;
-  co: number;
-  co2: string;
-  ch4: string;
-  temp: string;
-  pressureDiff: string;
-}
-
-export const DEVICE_MONITOR_ROWS: DeviceMonitorRow[] = Array.from({ length: 40 }, (_, index) => {
-  return {
-    deviceNo: `${(index % 4) + 1}#密闭`,
-    o2: (20.4 - (index % 10) * 0.07).toFixed(2),
-    co: 8 + (index % 12) * 2,
-    co2: (0.04 + (index % 9) * 0.004).toFixed(3),
-    ch4: (0.22 + (index % 8) * 0.03).toFixed(2),
-    temp: (25.8 + (index % 10) * 0.5).toFixed(1),
-    pressureDiff: (12 + (index % 7) * 3).toFixed(0),
-  };
-});

+ 16 - 18
src/views/vent/home/selfIgnition/goafOverview.adapter.ts

@@ -44,19 +44,15 @@ function includesAny(text: string, keywords: string[]) {
   return keywords.some((keyword) => source.includes(keyword.toLowerCase()));
 }
 
-function buildOverview(counts: GoafCountOverview | undefined, fallback: GoafOverviewItem[]): GoafOverviewItem[] {
-  if (!counts) return fallback;
-
-  const fallbackMap = new Map(fallback.map((item) => [item.label, item.value]));
-  const pick = (value: number | undefined, label: string) =>
-    value === null || value === undefined ? (fallbackMap.get(label) ?? 0) : toNumber(value);
+function buildOverview(counts: GoafCountOverview | undefined): GoafOverviewItem[] {
+  if (!counts) return [];
 
   return [
-    { label: '矿井采空区总数', value: pick(counts.totalCount, '矿井采空区总数') },
-    { label: '已封闭采空区数', value: pick(counts.closedCount, '已封闭采空区数') },
-    { label: '回撤工作面采空区数', value: pick(counts.withdrawCount, '回撤工作面采空区数') },
-    { label: '回采工作面采空区数', value: pick(counts.miningCount, '回采工作面采空区数') },
-    { label: '停产工作面采空区数', value: pick(counts.stoppedCount, '停产工作面采空区数') },
+    { label: '矿井采空区总数', value: toNumber(counts.totalCount) },
+    { label: '已封闭采空区数', value: toNumber(counts.closedCount) },
+    { label: '回撤工作面采空区数', value: toNumber(counts.withdrawCount) },
+    { label: '回采工作面采空区数', value: toNumber(counts.miningCount) },
+    { label: '停产工作面采空区数', value: toNumber(counts.stoppedCount) },
   ];
 }
 
@@ -74,12 +70,12 @@ function sumKindStatistics(statistics: DeviceKindStatistic[], keywords: string[]
   }, 0);
 }
 
-function buildDevices(statistics: DeviceStatistics | undefined, fallback: DeviceInstallItem[]): DeviceInstallItem[] {
-  if (!statistics) return fallback;
+function buildDevices(statistics: DeviceStatistics | undefined): DeviceInstallItem[] {
+  if (!statistics) return [];
 
   const typeStatistics = statistics.typeStatistics || [];
   const kindStatistics = statistics.kindStatistics || [];
-  if (!typeStatistics.length && !kindStatistics.length) return fallback;
+  if (!typeStatistics.length && !kindStatistics.length) return [];
 
   return DEVICE_BUCKETS.map((bucket) => {
     const typeCount = sumTypeStatistics(typeStatistics, bucket.typeKeywords);
@@ -144,12 +140,14 @@ function buildWarnings(summary: GoafOverviewSummary): WarningRow[] {
 }
 
 /** 将综合汇总接口转换为系统概览页面的展示数据 */
-export function mapGoafSummaryData(summary: GoafOverviewSummary | undefined, fallback: OverviewSummaryViewData): OverviewSummaryViewData {
-  if (!summary) return fallback;
+export function mapGoafSummaryData(summary: GoafOverviewSummary | undefined): OverviewSummaryViewData {
+  if (!summary) {
+    return { overview: [], devices: [], warnings: [] };
+  }
 
   return {
-    overview: buildOverview(summary.goafCountOverview, fallback.overview),
-    devices: buildDevices(summary.deviceStatistics, fallback.devices),
+    overview: buildOverview(summary.goafCountOverview),
+    devices: buildDevices(summary.deviceStatistics),
     warnings: buildWarnings(summary),
   };
 }

+ 52 - 49
src/views/vent/home/selfIgnition/index.vue

@@ -1,7 +1,7 @@
 <!-- eslint-disable vue/multi-word-component-names -->
 <template>
   <div ref="rootRef" class="ignition-home">
-    <div class="ignition-stage" :style="stageStyle">
+    <div class="ignition-stage">
       <!-- 顶部标题 -->
       <div v-if="!isEmbed" class="ignition-header">
         <div class="ignition-title">{{ pageTitle }}</div>
@@ -19,6 +19,11 @@
         <PanelSelect v-model="manageSystemId" :options="sceneOptions" />
       </div>
 
+      <!-- 中间三维模型 -->
+      <div class="ignition-model" :style="modelStyle">
+        <SubApp />
+      </div>
+
       <!-- 系统概览 -->
       <OverviewView v-show="activeTab === 0" :overview="data.overview" :devices="data.devices" :warnings="data.warnings" />
 
@@ -44,30 +49,49 @@
   import MonitorView from './components/MonitorView.vue';
   import ManualView from './components/ManualView.vue';
   import PanelSelect from './components/PanelSelect.vue';
-  import { createSelfIgnitionData } from './data';
+  import SubApp from '/@/components/vent/micro/createSubApp.vue';
   import { getSafetySceneList } from './safetyEvaluation.api';
   import { getGoafOverviewSummary } from './goafOverview.api';
   import { mapGoafSummaryData } from './goafOverview.adapter';
   import { FALLBACK_SCENE } from './evaluation.config';
+  import type { DeviceInstallItem, GoafOverviewItem, WarningRow } from './data';
   import type { SafetyScene } from './evaluation.config';
 
   const route = useRoute();
   const rootRef = ref<HTMLElement>();
-  const scaleX = ref(1);
-  const scaleY = ref(1);
   const activeTab = ref(0);
   const pageTitle = '张家峁煤自燃监测预警';
   const tabs = ['系统概览', '设备实时监测与分析', '人工录入与分析'];
-  const data = ref(createSelfIgnitionData());
+  const data = ref<{ overview: GoafOverviewItem[]; devices: DeviceInstallItem[]; warnings: WarningRow[] }>({
+    overview: [],
+    devices: [],
+    warnings: [],
+  });
   const scenes = ref<SafetyScene[]>([]);
   const manageSystemId = ref('');
 
-  let resizeObserver: ResizeObserver | undefined;
   let dataInterval: number | undefined;
   let summaryLoading = false;
 
   const isEmbed = computed(() => !!route.query.embed);
 
+  /** 三维模型按各页签的空白区域铺满(坐标基于 1920 × 928 画布) */
+  const MODEL_RECTS = [
+    { left: 413, top: 118, width: 1485, height: 502 }, // 系统概览
+    { left: 413, top: 118, width: 1092, height: 531 }, // 设备实时监测与分析
+    { left: 413, top: 118, width: 1092, height: 792 }, // 人工录入与分析
+  ];
+
+  const modelStyle = computed(() => {
+    const rect = MODEL_RECTS[activeTab.value] || MODEL_RECTS[0];
+    return {
+      left: `${rect.left}px`,
+      top: `${rect.top}px`,
+      width: `${rect.width}px`,
+      height: `${rect.height}px`,
+    };
+  });
+
   const sceneOptions = computed(() =>
     scenes.value.map((scene) => ({
       label: scene.systemname,
@@ -78,29 +102,6 @@
 
   const selectedSceneName = computed(() => scenes.value.find((scene) => scene.id === manageSystemId.value)?.systemname || '');
 
-  const stageStyle = computed(() => ({
-    transform: `translate(-50%, -50%) scale(${scaleX.value}, ${scaleY.value})`,
-  }));
-
-  /**
-   * 设计稿为 1920 × 1080。外层 AdaptiveContainer 已经把 1920 × 928 拉伸到视口,
-   * 这里按外层实际的 x / y 缩放比例做反向补偿,保证 1920 × 1080 的坐标始终精确落位。
-   */
-  function updateScale() {
-    const root = rootRef.value;
-    if (!root) return;
-    const rootWidth = root.clientWidth;
-    const rootHeight = root.clientHeight;
-    if (!rootWidth || !rootHeight) return;
-
-    const rect = root.getBoundingClientRect();
-    const outerScaleX = rect.width / rootWidth || 1;
-    const outerScaleY = rect.height / rootHeight || 1;
-    const fitScale = Math.min(rect.width / 1920, rect.height / 1080);
-
-    scaleX.value = fitScale / outerScaleX;
-    scaleY.value = fitScale / outerScaleY;
-  }
 
   /** 概览数据来自采空区综合汇总接口;接口异常时保留现有兜底数据 */
   async function refresh() {
@@ -110,7 +111,7 @@
       const res: any = await getGoafOverviewSummary();
       const summary = res?.result ?? res;
       if (!summary || typeof summary !== 'object') return;
-      const mapped = mapGoafSummaryData(summary, createSelfIgnitionData());
+      const mapped = mapGoafSummaryData(summary);
       data.value = { ...data.value, ...mapped };
     } catch {
       // 保持上一次成功数据,避免接口短暂异常导致页面回退为模拟数据
@@ -185,18 +186,10 @@
     void loadScenes();
     void refresh();
     initDataInterval();
-    updateScale();
-    if (typeof ResizeObserver !== 'undefined' && rootRef.value) {
-      resizeObserver = new ResizeObserver(updateScale);
-      resizeObserver.observe(rootRef.value);
-    }
-    window.addEventListener('resize', updateScale);
   });
 
   onUnmounted(() => {
     clearInterval(dataInterval);
-    resizeObserver?.disconnect();
-    window.removeEventListener('resize', updateScale);
   });
 </script>
 
@@ -213,12 +206,21 @@
   }
 
   .ignition-stage {
+    position: relative;
+    width: 100%;
+    height: 100%;
+  }
+
+  // 中间三维模型区域(与可配置首页一致,用 SubApp 挂载微前端三维场景)
+  .ignition-model {
     position: absolute;
-    left: 50%;
-    top: 50%;
-    width: 1920px;
-    height: 1080px;
-    transform-origin: center center;
+    z-index: 0;
+  }
+
+  // 视图容器本身不拦截鼠标,让中间的三维模型可拖拽/点击;
+  // 模块根节点已设置 pointer-events: auto,模块内交互不受影响。
+  :deep(.ignition-view) {
+    pointer-events: none;
   }
 
   .ignition-header {
@@ -227,7 +229,7 @@
     top: 0;
     z-index: 3;
     width: 100%;
-    height: 69px;
+    height: 59px;
     background: url('@/assets/images/vent/home/selfIgnition/top-bg.png') no-repeat center / 100% 100%;
   }
 
@@ -236,6 +238,7 @@
     align-items: center;
     justify-content: center;
     height: 100%;
+    padding-top: 10px;
     padding-bottom: 2px;
     box-sizing: border-box;
     font-family: 'douyuFont', sans-serif;
@@ -250,7 +253,7 @@
   .ignition-tabs {
     position: absolute;
     left: 50%;
-    top: 80px;
+    top: 69px;
     z-index: 4;
     display: flex;
     align-items: center;
@@ -289,7 +292,7 @@
     align-items: center;
     justify-content: center;
     width: 215px;
-    height: 48px;
+    height: 40px;
     box-sizing: border-box;
     border: none;
     background: url('@/assets/images/vent/home/selfIgnition/tab-item-bg.png') no-repeat center / 100% 100%;
@@ -320,15 +323,15 @@
   .scene-toolbar {
     position: absolute;
     left: 20px;
-    top: 70px;
+    top: 76px;
     z-index: 6;
     width: 393px;
-    height: 58px;
+    height: 46px;
   }
 
   :deep(.scene-toolbar .ignition-select) {
     width: 100%;
-    height: 58px;
+    height: 46px;
     padding: 0 44px 0 20px;
     box-sizing: border-box;
     border: none;

+ 1 - 1
src/views/vent/home/selfIgnition/safetyEvaluation.api.ts

@@ -67,7 +67,7 @@ export const getSafetyEvaluationByScene = (sceneId: string) => {
 };
 
 /** 场景类型:与系统其它页面一致,按场景类型 + pagetype=normal 查询 */
-const SCENE_STRTYPE = 'sys*';
+const SCENE_STRTYPE = 'sys_empty';
 
 /** 场景下拉列表,复用系统统一的场景管理接口(res.records: id / systemname) */
 export const getSafetySceneList = (params?: { strtype?: string; pagetype?: string; pageSize?: number }) =>

Vissa filer visades inte eftersom för många filer har ändrats