Ver código fonte

[Mod 0000]张家峁页面按照设计图进行第三版修改

wangkeyi 1 dia atrás
pai
commit
f376ff40eb

BIN
src/assets/images/vent/home/selfIgnition/1-7.png


BIN
src/assets/images/vent/home/selfIgnition/module-border-bottom-wide.png


BIN
src/assets/images/vent/home/selfIgnition/module-border-bottom.png


BIN
src/assets/images/vent/home/selfIgnition/module-border-middle-wide.png


BIN
src/assets/images/vent/home/selfIgnition/module-border-middle.png


BIN
src/assets/images/vent/home/selfIgnition/module-border-top-wide.png


BIN
src/assets/images/vent/home/selfIgnition/module-border-top.png


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


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


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


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


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


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


+ 140 - 176
src/views/vent/home/selfIgnition/components/ManualView.vue

@@ -1,14 +1,7 @@
 <template>
   <div class="ignition-view manual-view">
     <!-- 左:人工录入 -->
-    <ModuleCommon
-      :show-style="panelShowStyle(20, 132, 353, 907)"
-      :module-data="EMPTY_MODULE_DATA"
-      module-name="人工录入"
-      device-type="ignition_manual_input"
-      :data="{}"
-      :visible="true"
-    >
+    <Module :x="20" :y="132" :width="393" :height="907" title="人工录入">
       <div class="manual-form">
         <div class="form-toolbar">
           <div class="eval-type-tabs">
@@ -21,29 +14,23 @@
           <div v-if="loadingOptions" class="form-loading">评价指标加载中...</div>
           <template v-else>
             <div v-for="group in fieldGroups" :key="group.key" class="form-group">
-              <div class="group-collapse" @click="toggleGroup(group.key)">
-                <img class="group-icon" src="@/assets/images/vent/home/selfIgnition/form-icon.svg" alt="" />
-                <span>{{ group.title }}</span>
-                <i class="collapse-arrow" :class="{ collapsed: collapsed[group.key] }"></i>
+              <div class="group-title">
+                <span class="title-bars">
+                  <i v-for="n in 4" :key="n"></i>
+                </span>
+                <span>{{ group.title }}指标</span>
+                <span class="title-dots">
+                  <i></i>
+                  <b></b>
+                  <i></i>
+                </span>
               </div>
-              <template v-if="!collapsed[group.key]">
-                <div class="group-title">
-                  <span class="title-bars">
-                    <i v-for="n in 4" :key="n"></i>
-                  </span>
-                  <span>{{ group.title }}指标</span>
-                  <span class="title-dots">
-                    <i v-for="n in 3" :key="n"></i>
-                    <b></b>
-                  </span>
+              <div class="field-list">
+                <div v-for="item in group.fields" :key="item.code" class="field-row">
+                  <span class="field-label" :title="item.name">{{ item.name }}:</span>
+                  <PanelSelect v-model="formValues[FIELD_BY_CODE[item.code]]" :options="selectOptions(item)" />
                 </div>
-                <div class="field-list">
-                  <div v-for="item in group.fields" :key="item.code" class="field-row">
-                    <span class="field-label" :title="item.name">{{ item.name }}:</span>
-                    <PanelSelect v-model="formValues[FIELD_BY_CODE[item.code]]" :options="selectOptions(item)" />
-                  </div>
-                </div>
-              </template>
+              </div>
             </div>
             <div v-if="!fieldGroups.length" class="form-loading">暂无评价指标</div>
           </template>
@@ -58,28 +45,19 @@
           </button>
         </div>
       </div>
-    </ModuleCommon>
+    </Module>
 
     <!-- 右:评价结果 -->
-    <ModuleCommon
-      :show-style="panelShowStyle(1545, 132, 353, 907)"
-      :module-data="EMPTY_MODULE_DATA"
-      module-name="评价结果"
-      device-type="ignition_evaluation_result"
-      :data="{}"
-      :visible="true"
-    >
+    <Module :x="1505" :y="132" :width="393" :height="907" title="评价结果">
       <div class="result-panel">
         <div class="result-top">
           <div class="score-line">
-            <span class="score-label">安全评价得分:</span>
-            <img class="score-info" src="@/assets/images/vent/home/selfIgnition/info-icon.svg" alt="由后端算法计算" />
+            <span class="score-label">风险分值:</span>
             <span class="score-value">{{ resultScore }}</span>
           </div>
           <div class="gauge-line">
             <div class="gauge">
-              <img class="gauge-segment gauge-segment-1" src="@/assets/images/vent/home/selfIgnition/risk-gauge.png" alt="" />
-              <img class="gauge-segment gauge-segment-2" src="@/assets/images/vent/home/selfIgnition/risk-gauge.png" alt="" />
+              <img class="gauge-segment" src="@/assets/images/vent/home/selfIgnition/risk-gauge.png" alt="" />
             </div>
             <span class="risk-tag" :style="{ '--risk-color': resultRiskColor }">{{ resultTagText }}</span>
           </div>
@@ -96,9 +74,9 @@
         </div>
 
         <div class="level-table">
-          <div class="level-head"><span>评价等级</span><span>评分范围</span><span>对应颜色</span></div>
+          <div class="level-head"><span>评价等级</span><span>风险分值范围</span><span>对应颜色</span></div>
           <div
-            v-for="item in levels"
+            v-for="(item, index) in levels"
             :key="item.level"
             class="level-row"
             :class="{ highlight: item.level === resultLevel }"
@@ -106,6 +84,7 @@
           >
             <span class="level-name">
               <i :style="{ background: item.color, boxShadow: `0 0 8px ${item.color}` }"></i>
+              <b>{{ levelRoman(index) }}</b>
               {{ item.level }}
             </span>
             <span>{{ item.range }}</span>
@@ -113,15 +92,14 @@
           </div>
         </div>
       </div>
-    </ModuleCommon>
+    </Module>
   </div>
 </template>
 
 <script lang="ts" setup>
   import { computed, onMounted, reactive, ref, watch } from 'vue';
-  import ModuleCommon from '../../configurable/components/ModuleCommon.vue';
+  import Module from './Module.vue';
   import PanelSelect from './PanelSelect.vue';
-  import { EMPTY_MODULE_DATA, panelShowStyle } from '../utils';
   import { useMessage } from '/@/hooks/web/useMessage';
   import { calculateSafetyEvaluation, getSafetyEvaluationByScene, getSafetyItemOptions, saveSafetyEvaluation } from '../safetyEvaluation.api';
   import { EVAL_RISK_LEVELS, EVAL_RISK_MAP, FIELD_BY_CODE, FALLBACK_SAFETY_ITEMS } from '../evaluation.config';
@@ -137,7 +115,6 @@
   const items = ref<SafetyItem[]>([]);
   const evalType = ref(1);
   const formValues = reactive<Record<string, string>>({});
-  const collapsed = reactive<Record<string, boolean>>({});
   const evaluation = ref<SafetyEvaluationEntity | null>(null);
   const loadingOptions = ref(false);
   const previewing = ref(false);
@@ -172,7 +149,20 @@
   const resultLevel = computed(() => evaluation.value?.riskLevel || '');
   const resultLevelMeta = computed(() => EVAL_RISK_MAP[resultLevel.value] || null);
   const resultRiskColor = computed(() => resultLevelMeta.value?.color || '#3df6ff');
-  const resultTagText = computed(() => resultLevel.value || '未评价');
+
+  const ROMAN_NUMERALS = ['I', 'II', 'III', 'IV', 'V', 'VI'];
+
+  function levelRoman(index: number) {
+    return ROMAN_NUMERALS[index] || '';
+  }
+
+  const resultTagText = computed(() => {
+    const level = resultLevel.value;
+    if (!level) return '未评价';
+    const index = levels.findIndex((item) => item.level === level);
+    return index >= 0 ? `${levelRoman(index)} ${level}` : level;
+  });
+
   const resultTarget = computed(() => evaluation.value?.workfaceName || targetName.value);
   const resultTime = computed(() => evaluation.value?.createTime || '--');
 
@@ -180,7 +170,8 @@
     const value = evaluation.value?.totalScore;
     if (value === null || value === undefined || value === '') return '--';
     const score = Number(value);
-    return Number.isFinite(score) ? score.toFixed(2) : String(value);
+    // 与设计稿一致:最多保留两位小数并去掉末尾的 0(58.60 → 58.6)
+    return Number.isFinite(score) ? `${Number(score.toFixed(2))}` : String(value);
   });
 
   function selectOptions(item: SafetyItem) {
@@ -191,10 +182,6 @@
     }));
   }
 
-  function toggleGroup(key: string) {
-    collapsed[key] = !collapsed[key];
-  }
-
   function formatDateTime(date: Date) {
     const pad = (value: number) => `${value}`.padStart(2, '0');
     return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`;
@@ -356,6 +343,8 @@
 </script>
 
 <style lang="less" scoped>
+@import '/@/views/vent/home/selfIgnition/scrollbar.less';
+
   .manual-view {
     position: absolute;
     inset: 0;
@@ -427,14 +416,7 @@
     overflow-x: hidden;
     padding-right: 2px;
 
-    &::-webkit-scrollbar {
-      width: 4px;
-    }
-
-    &::-webkit-scrollbar-thumb {
-      background: rgba(61, 246, 255, 0.35);
-      border-radius: 2px;
-    }
+    .scrollbar-cyan();
   }
 
   .form-group {
@@ -445,56 +427,48 @@
     }
   }
 
-  .group-collapse {
+  .group-title {
+    position: relative;
     display: flex;
     align-items: center;
-    gap: 6px;
-    height: 34px;
-    padding: 0 8px;
-    border-left: 2px solid #3df6ff;
-    background: linear-gradient(90deg, rgba(15, 77, 120, 0.9), rgba(9, 43, 70, 0.15));
+    gap: 3px;
+    height: 22px;
+    margin-bottom: 4px;
+    padding: 0;
+    box-sizing: border-box;
     color: #fff;
-    font-size: 15px;
-    letter-spacing: 0.5px;
-    cursor: pointer;
-    user-select: none;
-  }
-
-  .group-icon {
-    width: 13px;
-    height: 15px;
-  }
-
-  .collapse-arrow {
-    margin-left: auto;
-    width: 0;
-    height: 0;
-    border-left: 4px solid transparent;
-    border-right: 4px solid transparent;
-    border-top: 5px solid #cfefff;
-    transition: transform 0.2s;
+    font-size: 16px;
+    font-weight: 600;
+    letter-spacing: 1px;
 
-    &.collapsed {
-      transform: rotate(-90deg);
+    // 底部的渐变光带(左侧亮、向右淡出至消失)
+    &::before {
+      content: '';
+      position: absolute;
+      left: 4px;
+      right: 0;
+      bottom: 0;
+      height: 13px;
+      background: linear-gradient(90deg, rgba(43, 143, 214, 0.55) 0%, rgba(24, 86, 140, 0.18) 45%, rgba(12, 40, 70, 0) 78%);
+      pointer-events: none;
     }
-  }
 
-  .group-title {
-    display: flex;
-    align-items: center;
-    gap: 6px;
-    height: 24px;
-    padding: 0 4px;
-    color: #a9dcf4;
-    font-size: 12px;
-    letter-spacing: 0.5px;
+    > * {
+      position: relative;
+      z-index: 1;
+    }
   }
 
   .title-bars {
+    position: relative;
     display: flex;
     align-items: flex-end;
-    gap: 2px;
-    height: 12px;
+    gap: 1px;
+    width: 14px;
+    height: 14px;
+    padding-bottom: 2px;
+    box-sizing: border-box;
+    border-bottom: 2px solid #6bd9ff;
 
     i {
       width: 3px;
@@ -505,36 +479,38 @@
       }
 
       &:nth-child(2) {
-        height: 12px;
+        height: 9px;
       }
 
       &:nth-child(3) {
-        height: 8px;
+        height: 12px;
       }
 
       &:nth-child(4) {
-        height: 4px;
+        height: 6px;
       }
     }
   }
 
   .title-dots {
+    position: absolute;
+    right: 10px;
+    bottom: 4px;
     display: flex;
     align-items: center;
     gap: 3px;
-    margin-left: auto;
 
     i {
-      width: 2px;
-      height: 2px;
-      background: rgba(61, 246, 255, 0.65);
+      width: 3px;
+      height: 3px;
+      background: rgba(110, 200, 255, 0.75);
     }
 
     b {
-      width: 3px;
-      height: 3px;
-      background: #3df6ff;
-      box-shadow: 0 0 4px rgba(61, 246, 255, 0.9);
+      width: 5px;
+      height: 5px;
+      background: #a9e6ff;
+      box-shadow: 0 0 5px rgba(61, 246, 255, 0.9);
     }
   }
 
@@ -604,90 +580,68 @@
   .result-panel {
     display: flex;
     flex-direction: column;
-    justify-content: space-evenly;
     height: 100%;
-    padding: 10px 12px 14px;
+    padding: 28px 12px 0;
     box-sizing: border-box;
   }
 
   .result-top {
-    display: flex;
     flex: none;
-    flex-direction: column;
-    justify-content: center;
-    height: 180px;
-    box-sizing: border-box;
-    background: url('@/assets/images/vent/home/selfIgnition/result-top-bg.png') no-repeat center / 100% 100%;
+    padding: 0 16px;
   }
 
   .score-line {
     display: flex;
     align-items: baseline;
-    padding: 0 20px;
+    justify-content: space-between;
   }
 
   .score-label {
     color: #fff;
-    font-size: 19px;
+    font-size: 34px;
+    line-height: 1;
     letter-spacing: 1px;
   }
 
-  .score-info {
-    width: 12px;
-    height: 12px;
-    margin-left: 5px;
-    align-self: center;
-    opacity: 0.85;
-  }
-
   .score-value {
-    margin-left: 16px;
     color: #fff;
-    font-size: 42px;
+    font-size: 54px;
     font-weight: 700;
     line-height: 1;
     letter-spacing: 1px;
-    text-shadow: 0 0 16px rgba(255, 255, 255, 0.35);
+    text-shadow: 0 0 16px rgba(255, 255, 255, 0.3);
   }
 
   .gauge-line {
     display: flex;
     align-items: center;
     justify-content: space-between;
-    margin-top: 26px;
-    padding: 0 18px;
+    margin-top: 12px;
   }
 
   .gauge {
     display: flex;
     align-items: center;
-    width: 150px;
-    height: 26px;
+    width: 149px;
+    height: 27px;
   }
 
   .gauge-segment {
-    width: 80px;
-    height: 22px;
-    object-fit: fill;
-
-    & + & {
-      margin-left: -8px;
-    }
-  }
-
-  .gauge-segment-2 {
-    opacity: 0.72;
+    display: block;
+    width: 100%;
+    height: 100%;
   }
 
   .risk-tag {
     display: flex;
     align-items: center;
+    justify-content: center;
     width: 159px;
     height: 34px;
-    padding-left: 22px;
+    padding: 0 12px 0 6px;
     box-sizing: border-box;
     color: #fff;
-    font-size: 15px;
+    font-size: 19px;
     font-weight: 600;
     letter-spacing: 0.5px;
     white-space: nowrap;
@@ -701,32 +655,34 @@
     display: flex;
     flex-direction: column;
     justify-content: center;
-    gap: 4px;
-    padding: 12px 16px;
-    border-left: 1px solid rgba(61, 246, 255, 0.16);
-    border-right: 1px solid rgba(61, 246, 255, 0.16);
-    background: rgba(7, 42, 70, 0.62);
+    width: calc(100% - 18px);
+    height: 139px;
+    margin: 38px auto 0;
+    padding: 0 20px;
+    box-sizing: border-box;
+    background: url('@/assets/images/vent/home/selfIgnition/result-top-bg.png') no-repeat center / 100% 100%;
   }
 
   .info-row {
     display: flex;
     align-items: center;
     justify-content: space-between;
-    height: 46px;
+    height: 34px;
     color: #fff;
-    font-size: 15px;
+    font-size: 19px;
     letter-spacing: 0.5px;
 
     em {
       color: #3df6ff;
       font-style: normal;
-      font-size: 16px;
+      font-size: 19px;
       text-shadow: 0 0 8px rgba(61, 246, 255, 0.35);
     }
   }
 
   .level-table {
     flex: none;
+    margin-top: 33px;
   }
 
   .level-head,
@@ -737,19 +693,17 @@
   }
 
   .level-head {
-    height: 40px;
-    border: 1px solid rgba(61, 246, 255, 0.4);
-    border-radius: 4px;
+    height: 32px;
     color: #3df6ff;
-    font-size: 13px;
+    font-size: 17px;
     background: url('@/assets/images/vent/home/selfIgnition/result-table-head.png') no-repeat center / 100% 100%;
 
     span:nth-child(1) {
-      width: 42%;
+      width: 36%;
     }
 
     span:nth-child(2) {
-      width: 32%;
+      width: 38%;
     }
 
     span:nth-child(3) {
@@ -759,17 +713,17 @@
 
   .level-row {
     position: relative;
-    height: 50px;
+    height: 59px;
     color: #e8f8ff;
-    font-size: 14px;
-    background: url('@/assets/images/vent/home/selfIgnition/result-row-glow.png') no-repeat center bottom / 100% 10px;
+    font-size: 17px;
+    background: url('@/assets/images/vent/home/selfIgnition/result-row-glow.png') no-repeat center bottom / 100% 25px;
 
     span:nth-child(1) {
-      width: 42%;
+      width: 36%;
     }
 
     span:nth-child(2) {
-      width: 32%;
+      width: 38%;
     }
 
     span:nth-child(3) {
@@ -777,10 +731,15 @@
     }
 
     &.highlight {
-      outline: 1px solid var(--highlight-color, #ff9d1c);
-      outline-offset: -1px;
-      background-color: rgba(255, 157, 28, 0.08);
-      box-shadow: inset 0 0 18px rgba(255, 157, 28, 0.16);
+      &::after {
+        content: '';
+        position: absolute;
+        inset: 2px;
+        border: 2px solid var(--highlight-color, #ff9d1c);
+        border-radius: 6px;
+        box-shadow: 0 0 10px rgba(255, 157, 28, 0.25);
+        pointer-events: none;
+      }
     }
   }
 
@@ -788,13 +747,18 @@
     display: flex;
     align-items: center;
     justify-content: center;
-    gap: 6px;
+    gap: 7px;
 
     i {
-      width: 7px;
-      height: 7px;
+      flex: none;
+      width: 9px;
+      height: 9px;
       border-radius: 50%;
     }
+
+    b {
+      font-weight: 600;
+    }
   }
 
   .action-button {

+ 134 - 0
src/views/vent/home/selfIgnition/components/Module.vue

@@ -0,0 +1,134 @@
+<template>
+  <div class="ignition-module" :class="{ 'is-wide': isWide }" :style="rootStyle">
+    <div class="module-top"></div>
+    <div class="module-body">
+      <slot></slot>
+    </div>
+    <div class="module-footer"></div>
+    <div class="module-header">
+      <span class="module-title" :title="title">{{ title }}</span>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { computed } from 'vue';
+
+  const props = defineProps<{
+    /** 设计稿坐标(1920 × 1080) */
+    x: number;
+    y: number;
+    width: number;
+    height: number;
+    title: string;
+  }>();
+
+  /** 宽模块(> 800)使用宽版三段边框图 */
+  const isWide = computed(() => props.width > 800);
+
+  const rootStyle = computed(() => ({
+    left: `${props.x}px`,
+    top: `${props.y}px`,
+    width: `${props.width}px`,
+    height: `${props.height}px`,
+  }));
+</script>
+
+<style lang="less" scoped>
+  .ignition-module {
+    position: absolute;
+    z-index: 1;
+    pointer-events: auto;
+
+    .module-top,
+    .module-footer {
+      position: absolute;
+      left: 0;
+      right: 0;
+      height: 48px;
+      background-repeat: no-repeat;
+      background-position: center;
+      background-size: 100% 100%;
+    }
+    .module-footer {
+      height: 30px;
+    }
+
+    .module-top {
+      top: 0;
+      background-image: url('@/assets/images/vent/home/selfIgnition/module-border-top.png');
+    }
+
+    .module-footer {
+      bottom: 0;
+      z-index: 1;
+      background-image: url('@/assets/images/vent/home/selfIgnition/module-border-bottom.png');
+      pointer-events: none;
+    }
+
+    // 正文从中段贴图开始,向上压住上盖下缘,与标题带衔接
+    .module-body {
+      position: absolute;
+      left: 0;
+      right: 0;
+      top: 48px;
+      bottom: 30px;
+      overflow: hidden;
+      background: url('@/assets/images/vent/home/selfIgnition/module-border-middle.png') no-repeat center / 100% 100%;
+    }
+
+    // 标题带(1-6)贴在模块上边框内侧
+    .module-header {
+      position: absolute;
+      top: 8px;
+      left: 8px;
+      right: 1px;
+      z-index: 2;
+      display: flex;
+      align-items: center;
+      height: 35px;
+      width: 400px;
+      padding: 0 12px 0 20px;
+      box-sizing: border-box;
+      background: url('@/assets/images/vent/home/selfIgnition/module-title-bg.png') no-repeat center / 100% 100%;
+      pointer-events: none;
+    }
+
+    .module-title {
+      display: flex;
+      align-items: center;
+      color: #fff;
+      font-size: 16px;
+      font-weight: 700;
+      letter-spacing: 1px;
+      white-space: nowrap;
+      text-shadow: 0 0 8px rgba(61, 246, 255, 0.45);
+
+      &::before {
+        content: '';
+        flex: none;
+        width: 9px;
+        height: 9px;
+        margin-right: 6px;
+        border: 2px solid #3df6ff;
+        background: linear-gradient(135deg, transparent 46%, rgba(61, 246, 255, 0.9) 47%, rgba(61, 246, 255, 0.9) 53%, transparent 54%);
+        box-shadow: 0 0 8px rgba(61, 246, 255, 0.45);
+        transform: rotate(45deg);
+      }
+    }
+
+    &.is-wide {
+      .module-top {
+        background-image: url('@/assets/images/vent/home/selfIgnition/module-border-top-wide.png');
+      }
+
+      .module-body {
+        background-image: url('@/assets/images/vent/home/selfIgnition/module-border-middle-wide.png');
+      }
+
+      .module-footer {
+        background-image: url('@/assets/images/vent/home/selfIgnition/module-border-bottom-wide.png');
+      }
+    }
+  }
+</style>

+ 129 - 159
src/views/vent/home/selfIgnition/components/MonitorView.vue

@@ -1,14 +1,7 @@
 <template>
   <div ref="viewRef" class="ignition-view monitor-view">
     <!-- 左上:自然发火阶段 -->
-    <ModuleCommon
-      :show-style="panelShowStyle(20, 132, 353, 578)"
-      :module-data="EMPTY_MODULE_DATA"
-      module-name="自然发火阶段"
-      device-type="ignition_fire_stage"
-      :data="{}"
-      :visible="true"
-    >
+    <Module :x="20" :y="132" :width="393" :height="578" title="自然发火阶段">
       <div class="stage-panel">
         <span class="stage-emblem">
           <img class="stage-emblem-frame" src="@/assets/images/vent/home/selfIgnition/2-1.png" alt="" />
@@ -38,17 +31,10 @@
           </div>
         </div>
       </div>
-    </ModuleCommon>
+    </Module>
 
     <!-- 右上:传感器监测 -->
-    <ModuleCommon
-      :show-style="panelShowStyle(1545, 77, 353, 328)"
-      :module-data="EMPTY_MODULE_DATA"
-      module-name="传感器监测"
-      device-type="ignition_sensor_monitor"
-      :data="{}"
-      :visible="true"
-    >
+    <Module :x="1505" :y="77" :width="393" :height="328" 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>
@@ -62,18 +48,10 @@
         <img src="@/assets/images/vent/no-data.png" alt="暂无数据" />
         <span>暂无数据</span>
       </div>
-    </ModuleCommon>
+    </Module>
 
     <!-- 右中:光纤测温 -->
-    <ModuleCommon
-      class="fiber-module"
-      :show-style="panelShowStyle(1545, 420, 353, 290)"
-      :module-data="EMPTY_MODULE_DATA"
-      module-name="光纤测温"
-      device-type="ignition_fiber_temperature"
-      :data="{}"
-      :visible="true"
-    >
+    <Module class="fiber-module" :x="1505" :y="420" :width="393" :height="290" 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>
@@ -103,18 +81,10 @@
         <img src="@/assets/images/vent/no-data.png" alt="暂无数据" />
         <span>暂无数据</span>
       </div>
-    </ModuleCommon>
+    </Module>
 
     <!-- 左下:束管监测 -->
-    <ModuleCommon
-      class="wide-module"
-      :show-style="panelShowStyle(20, 732, 930, 326)"
-      :module-data="EMPTY_MODULE_DATA"
-      module-name="束管监测"
-      device-type="ignition_bundle_monitor"
-      :data="{}"
-      :visible="true"
-    >
+    <Module class="wide-module" :x="20" :y="732" :width="930" :height="326" title="束管监测">
       <div v-if="displayBundleRows.length" class="table-panel">
         <div class="data-table bundle-table">
           <div class="table-head">
@@ -145,18 +115,10 @@
         <img src="@/assets/images/vent/no-data.png" alt="暂无数据" />
         <span>暂无数据</span>
       </div>
-    </ModuleCommon>
+    </Module>
 
     <!-- 右下:密闭监测 -->
-    <ModuleCommon
-      class="wide-module"
-      :show-style="panelShowStyle(969, 732, 929, 326)"
-      :module-data="EMPTY_MODULE_DATA"
-      module-name="密闭监测"
-      device-type="ignition_closed_monitor"
-      :data="{}"
-      :visible="true"
-    >
+    <Module class="wide-module" :x="969" :y="732" :width="929" :height="326" title="密闭监测">
       <div v-if="displayClosedRows.length" class="table-panel">
         <div class="data-table device-table">
           <div class="table-head">
@@ -187,15 +149,14 @@
         <img src="@/assets/images/vent/no-data.png" alt="暂无数据" />
         <span>暂无数据</span>
       </div>
-    </ModuleCommon>
+    </Module>
   </div>
 </template>
 
 <script lang="ts" setup>
-  import ModuleCommon from '../../configurable/components/ModuleCommon.vue';
+  import Module from './Module.vue';
   import FiberTemperatureChart from './FiberTemperatureChart.vue';
   import PanelSelect from './PanelSelect.vue';
-  import { EMPTY_MODULE_DATA, panelShowStyle } from '../utils';
   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';
@@ -542,6 +503,26 @@
     resetScrollPositions();
   }
 
+  /** 解析设备清单接口的返回(兼容 records 与 msgTxt 两种结构) */
+  function extractDeviceRows(res: any): any[] {
+    const payload = res?.result ?? res;
+    if (Array.isArray(payload?.records)) return payload.records;
+    if (Array.isArray(payload?.msgTxt)) {
+      return payload.msgTxt.reduce<any[]>((all, group) => all.concat(Array.isArray(group?.datalist) ? group.datalist : []), []);
+    }
+    return [];
+  }
+
+  /** 按系统统一的设备清单写法查询密闭设备(无需按场景过滤) */
+  async function loadClosedDevices(): Promise<any[]> {
+    try {
+      const res: any = await getMonitorDeviceList({ devicetype: 'obfurage_normal', pageSize: 10000 });
+      return extractDeviceRows(res);
+    } catch {
+      return [];
+    }
+  }
+
   async function loadMonitorDevices() {
     const systemID = props.manageSystemId;
     if (!systemID) return;
@@ -554,7 +535,10 @@
       const groups = getSceneGroups(res);
       apiBundleRows.value = buildBundleRows(collectGroupDevices(groups, 'bundletube'));
       apiSensorGroups.value = buildSensorGroups(collectGroupDevices(groups, 'modelsensor'));
-      apiClosedRows.value = buildClosedRows(collectGroupDevices(groups, 'obfurage'));
+
+      const closedDevices = await loadClosedDevices();
+      if (requestId !== deviceRequestSeq) return;
+      apiClosedRows.value = buildClosedRows(closedDevices.length ? closedDevices : collectGroupDevices(groups, 'obfurage'));
 
       const series = buildFiberSeries(collectGroupDevices(groups, 'fiber'));
       apiFiberSeries.value = series;
@@ -612,6 +596,8 @@
 </script>
 
 <style lang="less" scoped>
+@import '/@/views/vent/home/selfIgnition/scrollbar.less';
+
   .monitor-view {
     position: absolute;
     inset: 0;
@@ -648,17 +634,17 @@
     flex-direction: column;
     align-items: center;
     height: 100%;
-    padding: 74px 3px 12px;
+    padding: 72px 4px 0px;
     box-sizing: border-box;
   }
 
   .stage-emblem {
     position: absolute;
     left: 50%;
-    top: 14px;
+    top: 22px;
     z-index: 2;
     width: 110px;
-    height: 56px;
+    height: 46px;
     transform: translateX(-50%);
   }
 
@@ -672,8 +658,8 @@
     position: absolute;
     left: 50%;
     top: 50%;
-    width: 34px;
-    height: 42px;
+    width: 30px;
+    height: 36px;
     transform: translate(-50%, -50%);
     filter: drop-shadow(0 0 8px rgba(61, 246, 255, 0.9)) brightness(1.12);
   }
@@ -686,33 +672,36 @@
     flex-direction: column;
     align-items: center;
     width: 347px;
-    height: 137px;
-    padding-top: 14px;
+    height: 130px;
+    padding-top: 16px;
     box-sizing: border-box;
     background: url('@/assets/images/vent/home/selfIgnition/2-2.png') no-repeat center / 100% 100%;
   }
 
   .stage-level {
-    font-size: 38px;
-    font-weight: 700;
-    line-height: 40px;
-    letter-spacing: 2px;
+    font-size: 26px;
+    letter-spacing: 1px;
     white-space: nowrap;
-    text-shadow: 0 0 14px currentColor;
+    font-family: 'douyuFont';
   }
 
   .stage-eval-button {
-    width: 302px;
-    height: 72px;
-    margin-top: 6px;
+    position: absolute;
+    left: 50%;
+    bottom: 16px;
+    width: 280px;
+    height: 70px;
+    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: 20px;
-    letter-spacing: 1px;
+    font-size: 24px;
+    font-weight: 600;
+    letter-spacing: 2px;
     cursor: pointer;
     transition: filter 0.2s;
+    transform: translateX(-50%);
 
     &:hover {
       filter: brightness(1.12);
@@ -723,10 +712,8 @@
     display: flex;
     flex: 1;
     flex-direction: column;
-    width: 100%;
+    width: 364px;
     min-height: 0;
-    margin-top: 14px;
-    padding: 0 12px 12px;
     box-sizing: border-box;
     background: url('@/assets/images/vent/home/selfIgnition/2-5.png') no-repeat center / 100% 100%;
   }
@@ -736,33 +723,33 @@
     flex: none;
     align-items: flex-start;
     gap: 0;
-    min-height: 128px;
-    padding: 20px 4px 0 16px;
+    min-height: 130px;
+    padding: 12px 4px 0 26px;
     box-sizing: border-box;
   }
 
   .stage-warning-icon {
     position: relative;
     flex: none;
-    width: 90px;
-    height: 92px;
+    width: 107px;
+    height: 109px;
   }
 
   .stage-warning-pedestal {
     position: absolute;
     left: 0;
     bottom: 0;
-    width: 90px;
-    height: 92px;
+    width: 107px;
+    height: 109px;
     filter: drop-shadow(0 0 10px rgba(61, 246, 255, 0.35));
   }
 
   .stage-warning-bolt {
     position: absolute;
     left: 50%;
-    top: 12px;
-    width: 46px;
-    height: 46px;
+    top: 10px;
+    width: 52px;
+    height: 52px;
     transform: translateX(-50%);
     filter: drop-shadow(0 0 8px rgba(61, 246, 255, 0.65));
   }
@@ -771,6 +758,7 @@
     display: flex;
     flex-direction: column;
     min-width: 0;
+    margin-top: 12px;
     margin-left: 4px;
   }
 
@@ -783,27 +771,41 @@
   }
 
   .stage-warning-level {
-    margin-top: 26px;
-    padding-left: 12px;
-    font-size: 28px;
-    font-weight: 700;
-    font-style: italic;
-    line-height: 28px;
-    letter-spacing: 2px;
-    text-shadow: 0 0 12px currentColor;
+    margin-top: 22px;
+    font-size: 20px;
+    font-weight: 800;
+    line-height: 26px;
+    letter-spacing: 1px;
   }
 
   .stage-advice {
     position: relative;
     flex: none;
-    height: 125px;
+    width: 280px;
+    height: 130px;
     min-height: 0;
-    margin: 4px 18px 0;
+    margin: 9px 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%;
+
+    // 与上方预警信息之间的分隔线
+    &::before {
+      content: '';
+      position: absolute;
+      left: -2px;
+      right: -2px;
+      top: -12px;
+      height: 1px;
+      background: rgba(61, 246, 255, 0.5);
+    }
   }
 
   .stage-advice-title {
     position: absolute;
     z-index: 2;
+    top: -1px;
+    left: -1px;
     display: flex;
     align-items: center;
     width: 146px;
@@ -812,49 +814,45 @@
     box-sizing: border-box;
     background: url('@/assets/images/vent/home/selfIgnition/2-7.png') no-repeat center / 100% 100%;
     color: #fff;
-    font-size: 15px;
+    font-size: 16px;
     font-weight: 600;
     letter-spacing: 0.5px;
   }
 
   .stage-advice-content {
-    position: relative;
-    height: 100%;
-    padding: 34px 14px 12px 42px;
+    // 从标题下方开始滚动,避免滚动时文字钻到标题签下面
+    position: absolute;
+    left: 0;
+    right: 0;
+    top: 28px;
+    bottom: 0;
+    padding: 6px 10px 8px 38px;
     box-sizing: border-box;
-    overflow: hidden;
-    background: url('@/assets/images/vent/home/selfIgnition/2-6.png') no-repeat center / 100% 100%;
-    scrollbar-width: none;
-
-    &::-webkit-scrollbar {
-      display: none;
-    }
+    overflow-x: hidden;
+    overflow-y: auto;
+    .scrollbar-cyan();
 
     p {
       margin: 0;
       color: #fff;
-      font-size: 14px;
-      line-height: 23px;
+      font-size: 17px;
+      line-height: 26px;
       letter-spacing: 0.3px;
     }
   }
 
   .stage-advice-icon {
     position: absolute;
-    left: 18px;
-    top: 40px;
-    width: 9px;
-    height: 9px;
-    background: #f5222d;
-    box-shadow: 0 0 9px rgba(245, 34, 45, 0.85);
-    transform: rotate(45deg);
+    left: 14px;
+    top: 10px;
+    width: 14px;
+    height: 14px;
+    border-radius: 50%;
+    background: #e8362f;
+    box-shadow: 0 0 10px rgba(232, 54, 47, 0.85);
   }
 
   /* 光纤测温 */
-  :deep(.fiber-module .box1-center) {
-    height: calc(100% - 35px) !important;
-  }
-
   .fiber-panel {
     display: flex;
     flex-direction: column;
@@ -934,16 +932,19 @@
     height: 100%;
     padding: 8px 14px 0;
     box-sizing: border-box;
-    overflow: hidden;
+    overflow-x: hidden;
+    overflow-y: auto;
+    background: rgba(8, 66, 116, 0.45);
+    .scrollbar-cyan();
   }
 
   .sensor-group {
     position: relative;
     flex: none;
-    padding-top: 7px;
+    padding-top: 0;
 
     & + & {
-      margin-top: 4px;
+      margin-top: 8px;
     }
 
     &::before {
@@ -952,15 +953,8 @@
       top: 0;
       left: 0;
       right: 0;
-      height: 1px;
-      background: linear-gradient(
-        90deg,
-        rgba(61, 246, 255, 0.04),
-        rgba(61, 246, 255, 0.95) 12%,
-        rgba(61, 246, 255, 0.95) 88%,
-        rgba(61, 246, 255, 0.04)
-      );
-      box-shadow: 0 0 7px rgba(61, 246, 255, 0.45);
+      height: 2px;
+      background: #2cb6ff;
     }
   }
 
@@ -970,11 +964,11 @@
     align-items: center;
     width: 128px;
     height: 27px;
-    padding-left: 6px;
+    padding-left: 15px;
     box-sizing: border-box;
     background: url('@/assets/images/vent/home/selfIgnition/3-1.png') no-repeat center / 100% 100%;
     color: #3df6ff;
-    font-size: 17px;
+    font-size: 18px;
     font-weight: 700;
     line-height: 27px;
     letter-spacing: 1px;
@@ -985,13 +979,12 @@
     display: flex;
     align-items: center;
     justify-content: space-between;
-    height: 28px;
-    margin-top: 4px;
-    padding: 0 12px;
+    height: 24px;
+    margin-top: 6px;
+    padding: 0 18px;
     box-sizing: border-box;
-    border: 1px solid rgba(61, 246, 255, 0.16);
-    background: linear-gradient(90deg, rgba(9, 64, 104, 0.96), rgba(6, 45, 75, 0.9));
-    box-shadow: inset 0 0 8px rgba(61, 246, 255, 0.05);
+    border: none;
+    background: linear-gradient(90deg, rgba(14, 63, 109, 0.95), rgba(8, 49, 89, 0.9));
     color: #fff;
     font-size: 16px;
 
@@ -1015,16 +1008,7 @@
     }
   }
 
-  /* 底部宽表格面板:使用短边框图,保证标题和装饰点居中 */
-  :deep(.wide-module .box1-top) {
-    --image-box1-top: url('@/assets/images/vent/border/box1-top.png');
-    background-image: var(--image-box1-top) !important;
-  }
-
-  :deep(.wide-module .box1-bottom) {
-    --image-box1-bottom: url('@/assets/images/vent/border/box1-bottom.png');
-    background-image: var(--image-box1-bottom) !important;
-  }
+  /* 底部宽表格面板:使用宽版边框图 */
 
   .table-panel {
     display: flex;
@@ -1042,21 +1026,7 @@
     overflow-y: auto;
     border: 1px solid rgba(61, 246, 255, 0.55);
     background: rgba(6, 30, 52, 0.2);
-    scrollbar-width: thin;
-    scrollbar-color: rgba(61, 246, 255, 0.75) transparent;
-
-    &::-webkit-scrollbar {
-      width: 8px;
-    }
-
-    &::-webkit-scrollbar-track {
-      background: transparent;
-    }
-
-    &::-webkit-scrollbar-thumb {
-      border-radius: 4px;
-      background: linear-gradient(180deg, #3df6ff 0%, #0d7fc1 100%);
-    }
+    .scrollbar-cyan();
   }
 
   .table-head,

+ 16 - 98
src/views/vent/home/selfIgnition/components/OverviewView.vue

@@ -1,15 +1,7 @@
 <template>
   <div class="ignition-view overview-view">
     <!-- 左:矿井采空区概览 -->
-    <ModuleCommon
-      class="overview-module"
-      :show-style="panelShowStyle(20, 114, 393, 576)"
-      :module-data="EMPTY_MODULE_DATA"
-      module-name="矿井采空区概览"
-      device-type="ignition_goaf_overview"
-      :data="{}"
-      :visible="true"
-    >
+    <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">
           <span class="goaf-icon">
@@ -19,18 +11,10 @@
           <span class="goaf-value">{{ item.value }}</span>
         </div>
       </div>
-    </ModuleCommon>
+    </Module>
 
     <!-- 左下:安装设备情况 -->
-    <ModuleCommon
-      class="install-module"
-      :show-style="panelShowStyle(20, 722, 393, 336)"
-      :module-data="EMPTY_MODULE_DATA"
-      module-name="安装设备情况"
-      device-type="ignition_device_install"
-      :data="{}"
-      :visible="true"
-    >
+    <Module class="install-module" :x="20" :y="722" :width="393" :height="336" title="安装设备情况">
       <div class="install-panel">
         <div
           v-for="(device, index) in devices"
@@ -52,18 +36,10 @@
           >
         </div>
       </div>
-    </ModuleCommon>
+    </Module>
 
     <!-- 右下:分级预警表 -->
-    <ModuleCommon
-      class="table-module"
-      :show-style="panelShowStyle(433, 722, 1465, 336)"
-      :module-data="EMPTY_MODULE_DATA"
-      module-name="矿井采空区分级预警"
-      device-type="ignition_warning_table"
-      :data="{}"
-      :visible="true"
-    >
+    <Module class="table-module" :x="433" :y="722" :width="1465" :height="336" title="矿井采空区分级预警">
       <div class="warning-table-panel">
         <div class="warning-table">
           <div class="table-head">
@@ -91,14 +67,13 @@
           </div>
         </div>
       </div>
-    </ModuleCommon>
+    </Module>
   </div>
 </template>
 
 <script lang="ts" setup>
   import { computed } from 'vue';
-  import ModuleCommon from '../../configurable/components/ModuleCommon.vue';
-  import { EMPTY_MODULE_DATA, panelShowStyle } from '../utils';
+  import Module from './Module.vue';
   import type { DeviceInstallItem, GoafOverviewItem, WarningRow } from '../data';
   import bundleMonitorIcon from '@/assets/images/vent/home/selfIgnition/install-bundle-monitor.svg';
   import fiberTemperatureIcon from '@/assets/images/vent/home/selfIgnition/install-fiber-temperature.svg';
@@ -131,43 +106,25 @@
 </script>
 
 <style lang="less" scoped>
+@import '/@/views/vent/home/selfIgnition/scrollbar.less';
+
   .overview-view {
     position: absolute;
     inset: 0;
   }
 
-  :deep(.overview-module .box1-center),
-  :deep(.install-module .box1-center),
-  :deep(.table-module .box1-center) {
-    height: calc(100% - 35px) !important;
-  }
-
   .overview-panel {
     display: flex;
     flex-direction: column;
     justify-content: space-evenly;
     gap: 24px;
     height: 100%;
-    padding: 16px 10px;
+    padding: 0px 10px 0px 20px;
     box-sizing: border-box;
     overflow-x: hidden;
     overflow-y: auto;
     scrollbar-gutter: stable;
-    scrollbar-width: thin;
-    scrollbar-color: rgba(61, 246, 255, 0.75) transparent;
-
-    &::-webkit-scrollbar {
-      width: 8px;
-    }
-
-    &::-webkit-scrollbar-track {
-      background: transparent;
-    }
-
-    &::-webkit-scrollbar-thumb {
-      border-radius: 4px;
-      background: linear-gradient(180deg, #3df6ff 0%, #0d7fc1 100%);
-    }
+    .scrollbar-cyan();
   }
 
   .goaf-item {
@@ -233,21 +190,7 @@
     box-sizing: border-box;
     overflow-x: hidden;
     overflow-y: auto;
-    scrollbar-width: thin;
-    scrollbar-color: rgba(61, 246, 255, 0.75) transparent;
-
-    &::-webkit-scrollbar {
-      width: 8px;
-    }
-
-    &::-webkit-scrollbar-track {
-      background: transparent;
-    }
-
-    &::-webkit-scrollbar-thumb {
-      border-radius: 4px;
-      background: linear-gradient(180deg, #3df6ff 0%, #0d7fc1 100%);
-    }
+    .scrollbar-cyan();
   }
 
   .install-item {
@@ -341,33 +284,19 @@
     display: flex;
     flex-direction: column;
     height: 100%;
-    padding: 23px 22px 0;
+    padding: 8px 22px 0;
     box-sizing: border-box;
   }
 
   .warning-table {
-    flex: none;
-    height: 251px;
+    flex: 1 1 auto;
+    height: 100%;
     min-height: 0;
     box-sizing: border-box;
     overflow-y: auto;
     border: 1px solid rgba(61, 246, 255, 0.55);
     background: rgba(6, 30, 52, 0.2);
-    scrollbar-width: thin;
-    scrollbar-color: rgba(61, 246, 255, 0.75) transparent;
-
-    &::-webkit-scrollbar {
-      width: 8px;
-    }
-
-    &::-webkit-scrollbar-track {
-      background: transparent;
-    }
-
-    &::-webkit-scrollbar-thumb {
-      border-radius: 4px;
-      background: linear-gradient(180deg, #3df6ff 0%, #0d7fc1 100%);
-    }
+    .scrollbar-cyan();
   }
 
   .table-head,
@@ -456,15 +385,4 @@
     width: 12px;
     height: 15px;
   }
-
-  /* 表格面板较宽,使用短边框图拉伸,保证顶部/底部装饰点居中 */
-  :deep(.table-module .box1-top) {
-    --image-box1-top: url('@/assets/images/vent/border/box1-top.png');
-    background-image: var(--image-box1-top) !important;
-  }
-
-  :deep(.table-module .box1-bottom) {
-    --image-box1-bottom: url('@/assets/images/vent/border/box1-bottom.png');
-    background-image: var(--image-box1-bottom) !important;
-  }
 </style>

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

@@ -151,7 +151,7 @@
   async function loadScenes() {
     let list: SafetyScene[] = [];
     try {
-      const res: any = await getSafetySceneList({ pagetype: 'normal' });
+      const res: any = await getSafetySceneList();
       list = extractSceneRows(res)
         .map(toSafetyScene)
         .filter((scene) => !!scene.id);
@@ -159,7 +159,7 @@
       list = [];
     }
 
-    // /monitor/system 未返回列表时,使用综合汇总中的采空区场景兜底
+    // 场景接口未返回列表时,使用综合汇总中的采空区场景兜底
     if (!list.length) {
       list = await loadScenesFromSummary();
     }
@@ -250,66 +250,92 @@
   .ignition-tabs {
     position: absolute;
     left: 50%;
-    top: 64px;
+    top: 80px;
     z-index: 4;
     display: flex;
     align-items: center;
     justify-content: center;
-    gap: 12px;
-    width: 579px;
-    height: 68px;
-    padding: 13px 16px 9px;
-    box-sizing: border-box;
+    gap: 10px;
+    height: 48px;
     transform: translateX(-50%);
-    background: url('@/assets/images/vent/home/selfIgnition/tab-bg.png') no-repeat center / 100% 100%;
+
+    // 标签组两侧向外延伸的斜翼装饰线
+    &::before,
+    &::after {
+      content: '';
+      position: absolute;
+      bottom: 0;
+      width: 216px;
+      height: 39px;
+      background-repeat: no-repeat;
+      background-position: center;
+      background-size: 100% 100%;
+      pointer-events: none;
+    }
+
+    &::before {
+      right: 100%;
+      background-image: url('@/assets/images/vent/home/selfIgnition/tab-wing-left.png');
+    }
+
+    &::after {
+      left: 100%;
+      background-image: url('@/assets/images/vent/home/selfIgnition/tab-wing-right.png');
+    }
   }
 
   .ignition-tab {
     display: flex;
     align-items: center;
     justify-content: center;
-    width: 162px;
-    height: 40px;
+    width: 215px;
+    height: 48px;
     box-sizing: border-box;
     border: none;
     background: url('@/assets/images/vent/home/selfIgnition/tab-item-bg.png') no-repeat center / 100% 100%;
-    color: rgba(255, 255, 255, 0.86);
-    font-size: 15px;
+    color: #e6f7ff;
+    font-size: 18px;
+    font-weight: 700;
     letter-spacing: 0.5px;
     white-space: nowrap;
     cursor: pointer;
     transition:
       color 0.2s,
-      border-color 0.2s,
-      box-shadow 0.2s;
+      filter 0.2s;
 
     &:hover {
       color: #fff;
+      filter: drop-shadow(0 0 6px rgba(61, 246, 255, 0.45));
     }
 
     &.active {
       background: url('@/assets/images/vent/home/selfIgnition/tab-active-bg.png') no-repeat center / 100% 100%;
+      color: #fff;
+      text-shadow:
+        0 0 8px rgba(61, 246, 255, 0.55),
+        0 1px 2px rgba(0, 0, 0, 0.6);
     }
   }
 
   .scene-toolbar {
     position: absolute;
     left: 20px;
-    top: 76px;
+    top: 70px;
     z-index: 6;
-    width: 357px;
-    height: 52px;
+    width: 393px;
+    height: 58px;
   }
 
   :deep(.scene-toolbar .ignition-select) {
     width: 100%;
-    height: 52px;
-    padding: 0 48px 0 86px;
+    height: 58px;
+    padding: 0 44px 0 20px;
     box-sizing: border-box;
     border: none;
     border-radius: 0;
     background: url('@/assets/images/vent/home/selfIgnition/1-7.png') no-repeat center / 100% 100%;
-    font-size: 17px;
+    font-size: 20px;
+    font-weight: 600;
     letter-spacing: 0.5px;
 
     &:hover,
@@ -320,10 +346,10 @@
   }
 
   :deep(.scene-toolbar .ignition-select-arrow) {
-    right: 30px;
-    width: 12px;
-    height: 12px;
-    margin-top: -7px;
+    right: 18px;
+    width: 14px;
+    height: 14px;
+    margin-top: -9px;
     border: none;
     border-right: 2px solid #eaffff;
     border-bottom: 2px solid #eaffff;
@@ -331,21 +357,7 @@
   }
 
   :deep(.scene-toolbar .ignition-select.open .ignition-select-arrow) {
-    margin-top: -3px;
+    margin-top: -4px;
     transform: rotate(225deg);
   }
-
-  :deep(.box1-top .title) {
-    color: #fff;
-    font-size: 16px;
-    font-weight: 700;
-    letter-spacing: 1px;
-    text-shadow: 0 0 8px rgba(61, 246, 255, 0.35);
-    transform: translateY(2px);
-  }
-
-  :deep(.box1-center > .box-container) {
-    background-color: #062441 !important;
-    background-image: none;
-  }
 </style>

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

@@ -10,7 +10,7 @@ enum Api {
   update = '/safety/safetyEvaluation/updateSafetyEvaluation',
   remove = '/safety/safetyEvaluation/deleteSafetyEvaluation',
   getByScene = '/safety/safetyEvaluation/getByScene',
-  sceneList = '/monitor/system',
+  sceneList = '/safety/ventanalyManageSystem/list',
 }
 
 /** 22 项评价指标、权重和选项字典 */
@@ -66,5 +66,18 @@ export const getSafetyEvaluationByScene = (sceneId: string) => {
   return promise;
 };
 
-/** 采空区场景列表,用于评价对象绑定 */
-export const getSafetySceneList = (params?: Record<string, any>) => defHttp.post({ url: Api.sceneList, params: params ?? {} });
+/** 场景类型:与系统其它页面一致,按场景类型 + pagetype=normal 查询 */
+const SCENE_STRTYPE = 'sys*';
+
+/** 场景下拉列表,复用系统统一的场景管理接口(res.records: id / systemname) */
+export const getSafetySceneList = (params?: { strtype?: string; pagetype?: string; pageSize?: number }) =>
+  defHttp.get({
+    url: Api.sceneList,
+    params: {
+      strtype: params?.strtype ?? SCENE_STRTYPE,
+      pagetype: params?.pagetype ?? 'normal',
+      // 该接口默认每页 10 条,需显式传 pageSize 才能取全
+      pageSize: params?.pageSize ?? 1000,
+      pageNo: 1,
+    },
+  });

+ 23 - 0
src/views/vent/home/selfIgnition/scrollbar.less

@@ -0,0 +1,23 @@
+/**
+ * 自燃监测页统一滚动条样式:
+ * 6px 宽、青色渐变滑块、透明轨道、无上下箭头按钮。
+ */
+.scrollbar-cyan() {
+  &::-webkit-scrollbar {
+    width: 6px;
+    height: 6px;
+  }
+
+  &::-webkit-scrollbar-button {
+    display: none;
+  }
+
+  &::-webkit-scrollbar-track {
+    background: transparent;
+  }
+
+  &::-webkit-scrollbar-thumb {
+    border-radius: 3px;
+    background: linear-gradient(180deg, #3df6ff 0%, #0d7fc1 100%);
+  }
+}