Bläddra i källkod

隐患提示界面重构

asuka-4908 3 veckor sedan
förälder
incheckning
d48dc6a75a
2 ändrade filer med 340 tillägg och 44 borttagningar
  1. 0 3
      package-lock.json
  2. 340 41
      src/views/tips_report.vue

+ 0 - 3
package-lock.json

@@ -1568,7 +1568,6 @@
       "integrity": "sha512-B5j0rYMlinhhOo9tjQebMVVn0TfyXAF+wB3b2ggZUuJ/is/Y+7+JGjirAMxHZ9Z3hIP98NPfamlAkBHa1lAaXQ==",
       "dev": true,
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "chokidar": "^5.0.0",
         "immutable": "^5.1.5",
@@ -1599,7 +1598,6 @@
       "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==",
       "dev": true,
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "esbuild": "^0.21.3",
         "postcss": "^8.4.43",
@@ -1659,7 +1657,6 @@
       "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.35.tgz",
       "integrity": "sha512-cx89fnr+0kVGHiNFG6y6s0bdjypJRFNZn6x3WPstNdQR1bi1mbB7h4v5IBGTsPJU3nK1+0Iqj3Zf+hZWMieR4Q==",
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "@vue/compiler-dom": "3.5.35",
         "@vue/compiler-sfc": "3.5.35",

+ 340 - 41
src/views/tips_report.vue

@@ -137,16 +137,46 @@
         <div class="right-panel">
           <div class="panel-section">
             <div class="section-header">
-              <span class="section-title">建议整改清单</span>
+              <span class="section-title">检测要素</span>
+              <span class="section-count">5</span>
             </div>
             <div class="checklist">
               <div
-                v-for="(item, index) in currentTask.checklist"
-                :key="index"
-                :class="['checklist-item', { checked: item.checked }]"
+                v-for="group in detectionGroups"
+                :key="group.id"
+                :class="['check-group', { expanded: expandedGroupId === group.id }]"
               >
-                <input type="checkbox" :checked="item.checked" @change="toggleCheck(index)" />
-                <span>{{ item.text }}</span>
+                <button class="check-group-header" type="button" @click="toggleGroup(group.id)">
+                  <div class="check-group-title">
+                    <span class="group-index">{{ group.id }}</span>
+                    <span>{{ group.title }}</span>
+                  </div>
+                  <div class="group-meta">
+                    <span>{{ group.items.length }} 项</span>
+                    <span class="group-caret">▶</span>
+                  </div>
+                </button>
+                <div
+                  v-for="(item, index) in group.items"
+                  v-show="expandedGroupId === group.id"
+                  :key="`${group.id}-${index}`"
+                  class="checklist-row"
+                >
+                  <div class="checklist-item">
+                    <span class="item-index">{{ index + 1 }}</span>
+                    <span class="item-text">{{ item.text }}</span>
+                  </div>
+                  <div class="case-examples">
+                    <div class="case-card positive">
+                      <div class="case-title">正确示例</div>
+                      <img src="/case-positive.png" alt="正确示例" />
+                    </div>
+                    <div class="case-card negative">
+                      <div class="case-title">错误示例</div>
+                      <img src="/case-negative.png" alt="错误示例" />
+                    </div>
+                  </div>
+                </div>
               </div>
             </div>
           </div>
@@ -178,11 +208,26 @@ const taskList = ref([
       { label: '配电箱', top: '45%', left: '18%' },
     ],
     checklist: [
-      { text: '请检查外观是否整洁,是否存在油污堆积;检查外观是否整洁,是否存在油污堆积;检查外观是否整洁,是否存在油污堆积', checked: false },
-      { text: '请确认加油机输油管及阀门连接是否牢固,定期进行紧固检查,以防泄漏或松动;检查外观是否整洁,是否存在油污堆积', checked: false },
-      { text: '请检查灭火器是否在有效期内,压力是否正常,放置位置是否便于取用;检查外观是否整洁,是否存在油污堆积', checked: false },
-      { text: '请检查配电箱及线路是否规范,是否存在私拉乱接;检查外观是否整洁,是否存在油污堆积', checked: false },
-      { text: '请检查防撞柱是否完好,高度是否符合要求,表面反光标识是否清晰;检查外观是否整洁,是否存在油污堆积', checked: false },
+      { text: '加油机外观不整洁,有明显油污' },
+      { text: '机座地脚螺栓明显松动' },
+      { text: '加油机紧固件连接明显松动' },
+      { text: '加油机底部填沙潮湿' },
+      { text: '加油机底部填沙有明显油迹' },
+      { text: '进油管与紧急截断阀连接处未露出沙外' },
+      { text: '油品管线连接处有明显渗漏' },
+      { text: '过滤器有明显油污和渗漏' },
+      { text: '加油机底部未设置截断阀' },
+      { text: '加油软管上未设置安全拉断阀' },
+      { text: '加油枪密封不良,工作时出现明显渗漏' },
+      { text: '汽油加油枪无集气罩' },
+      { text: '加油枪集气罩破损' },
+      { text: '油气回收检测口的丝堵松动' },
+      { text: '油气回收管路渗油' },
+      { text: '加油机静电接地失效' },
+      { text: '加油机铭牌不清晰' },
+      { text: '加油机工艺仓与电气仓之间隔板上的孔洞未密封' },
+      { text: '加油机内防爆挠性管连接明显松动' },
+      { text: '防爆接线盒未在专用接地端子处进行静电接地连接' },
     ]
   },
   {
@@ -248,8 +293,106 @@ const currentTask = computed(() => {
   return taskList.value.find(t => t.id === currentTaskId.value) || taskList.value[0]
 })
 
+const detectionGroups = computed(() => [
+  {
+    id: 1,
+    title: '加油机',
+    items: currentTask.value.checklist
+  },
+  {
+    id: 2,
+    title: '加油机输油软管',
+    items: [
+      { text: '输油软管外观存在老化、开裂或磨损' },
+      { text: '软管连接接头有明显松动' },
+      { text: '软管与加油枪连接处存在渗漏' },
+      { text: '软管与加油机连接处存在渗漏' },
+      { text: '软管未设置安全拉断阀' },
+      { text: '安全拉断阀安装方向不符合要求' },
+      { text: '安全拉断阀外观破损或锈蚀' },
+      { text: '软管拖地或受车辆碾压风险明显' },
+      { text: '软管长度不符合现场使用要求' },
+      { text: '软管表面有明显油污' },
+      { text: '软管弯折半径过小' },
+      { text: '软管固定支架缺失或损坏' },
+      { text: '软管回位装置失效' },
+      { text: '软管标识不清晰' },
+      { text: '软管未按要求定期检查' },
+      { text: '软管耐压等级标识缺失' },
+      { text: '软管附近存在明火或高温风险' },
+      { text: '软管连接密封件老化' },
+      { text: '软管防静电连接失效' },
+      { text: '软管收纳区域通行受阻' },
+    ]
+  },
+  {
+    id: 3,
+    title: '防撞栏',
+    items: [
+      { text: '防撞栏缺失或设置位置不合理' },
+      { text: '防撞栏固定螺栓松动' },
+      { text: '防撞栏立柱变形或倾斜' },
+      { text: '防撞栏表面反光标识不清晰' },
+      { text: '防撞栏警示颜色脱落' },
+      { text: '防撞栏高度不符合要求' },
+      { text: '防撞栏基础破损' },
+      { text: '防撞栏与设备间距不足' },
+      { text: '车辆通行区域防护不足' },
+      { text: '防撞设施周边存在杂物堆放' },
+      { text: '防撞栏夜间可视性不足' },
+      { text: '防撞栏维修记录缺失' },
+      { text: '防撞栏端部未做安全处理' },
+    ]
+  },
+  {
+    id: 4,
+    title: '支撑柱/立柱',
+    items: [
+      { text: '支撑柱外观存在明显裂缝' },
+      { text: '支撑柱表面防腐层脱落' },
+      { text: '立柱底座固定件松动' },
+      { text: '立柱根部存在积水或锈蚀' },
+      { text: '立柱附近防撞措施不足' },
+      { text: '立柱警示标识不清晰' },
+      { text: '立柱垂直度异常' },
+      { text: '立柱与棚体连接处异常' },
+      { text: '支撑结构存在明显变形' },
+      { text: '立柱周边通行空间不足' },
+      { text: '立柱维护检查记录缺失' },
+    ]
+  },
+  {
+    id: 5,
+    title: '加油枪',
+    items: [
+      { text: '加油枪外观破损或变形' },
+      { text: '加油枪密封不良' },
+      { text: '加油枪工作时出现明显渗漏' },
+      { text: '汽油加油枪无集气罩' },
+      { text: '加油枪集气罩破损' },
+      { text: '枪嘴磨损或变形' },
+      { text: '加油枪开关回位不灵活' },
+      { text: '加油枪自封功能异常' },
+      { text: '加油枪挂枪座损坏' },
+      { text: '加油枪与软管连接处松动' },
+      { text: '加油枪标识不清晰' },
+      { text: '加油枪存在油污堆积' },
+      { text: '油气回收接口松动' },
+      { text: '油气回收通道堵塞' },
+      { text: '加油枪防静电连接异常' },
+      { text: '加油枪使用区域照明不足' },
+      { text: '加油枪放置位置不规范' },
+      { text: '加油枪附近存在杂物' },
+      { text: '加油枪未按要求定期维护' },
+      { text: '加油枪维修更换记录缺失' },
+    ]
+  },
+])
+
+const expandedGroupId = ref(null)
 const selectTask = (task) => {
   currentTaskId.value = task.id
+  expandedGroupId.value = null
 }
 
 const selectTag = (tag) => {
@@ -261,6 +404,10 @@ const toggleCheck = (index) => {
     currentTask.value.checklist[index].checked = !currentTask.value.checklist[index].checked
   }
 }
+
+const toggleGroup = (groupId) => {
+  expandedGroupId.value = expandedGroupId.value === groupId ? null : groupId
+}
 </script>
 
 <style scoped lang="scss">
@@ -423,22 +570,21 @@ const toggleCheck = (index) => {
 }
 
 .content-body {
-  display: flex;
+  display: grid;
+  grid-template-columns: minmax(0, 1fr) 360px;
+  grid-template-rows: auto minmax(0, 1fr);
   gap: 20px;
   flex: 1;
   overflow: hidden;
 }
 
 .center-panel {
-  flex: 1;
-  display: flex;
-  flex-direction: column;
-  gap: 20px;
-  overflow-y: auto;
-  padding-right: 8px;
+  display: contents;
 }
 
 .image-section {
+  grid-column: 1;
+  grid-row: 1;
   position: relative;
   background: #fff;
   border-radius: 12px;
@@ -488,11 +634,18 @@ const toggleCheck = (index) => {
 }
 
 .ai-section {
+  grid-column: 2;
+  grid-row: 1 / 3;
+  align-self: stretch;
   background: #fff;
   border-radius: 12px;
   padding: 16px;
   box-shadow: 0 1px 4px rgba(0,0,0,0.05);
-  flex-shrink: 0;
+  min-height: 0;
+  height: auto;
+  overflow: hidden;
+  display: flex;
+  flex-direction: column;
 
   .section-header {
     display: flex;
@@ -509,6 +662,9 @@ const toggleCheck = (index) => {
   }
 
   .ai-content {
+    flex: 1;
+    overflow-y: auto;
+
     h4 {
       font-size: 14px;
       font-weight: 600;
@@ -652,8 +808,11 @@ const toggleCheck = (index) => {
 }
 
 .right-panel {
-  width: 360px;
-  flex-shrink: 0;
+  grid-column: 1;
+  grid-row: 2;
+  min-width: 0;
+  min-height: 0;
+  overflow: hidden;
 }
 
 .panel-section {
@@ -662,6 +821,7 @@ const toggleCheck = (index) => {
   padding: 16px;
   box-shadow: 0 1px 4px rgba(0,0,0,0.05);
   height: 100%;
+  min-height: 0;
   display: flex;
   flex-direction: column;
   overflow: hidden;
@@ -670,46 +830,185 @@ const toggleCheck = (index) => {
     display: flex;
     justify-content: space-between;
     align-items: center;
-    margin-bottom: 12px;
+    margin-bottom: 16px;
     flex-shrink: 0;
 
     .section-title {
-      font-size: 16px;
-      font-weight: 500;
+      font-size: 18px;
+      font-weight: 700;
       color: #333;
     }
+
+    .section-count {
+      width: 28px;
+      height: 28px;
+      border-radius: 50%;
+      background: #3f7cff;
+      color: #fff;
+      display: inline-flex;
+      align-items: center;
+      justify-content: center;
+      font-size: 15px;
+      font-weight: 700;
+    }
   }
 
   .checklist {
     flex: 1;
     overflow-y: auto;
+    padding-right: 4px;
 
-    .checklist-item {
+    .check-group {
+      border: 1px solid #d9dee8;
+      border-radius: 8px;
+      overflow: hidden;
+      background: #f8fafc;
+      margin-bottom: 10px;
+
+      &.expanded {
+        border-color: #6c79ff;
+        background: #fff;
+
+        .check-group-header {
+          background: #efedff;
+        }
+
+        .group-caret {
+          transform: rotate(90deg);
+        }
+      }
+    }
+
+    .check-group-header {
       display: flex;
-      align-items: flex-start;
-      padding: 10px 0;
-      border-bottom: 1px solid #f5f5f5;
+      justify-content: space-between;
+      align-items: center;
+      width: 100%;
+      min-height: 48px;
+      padding: 0 14px;
+      border: 0;
+      background: #f8fafc;
+      color: #26324d;
+      font-size: 16px;
+      font-weight: 700;
+      cursor: pointer;
+    }
+
+    .check-group-title,
+    .group-meta {
+      display: flex;
+      align-items: center;
+      gap: 10px;
+    }
+
+    .group-index {
+      width: 22px;
+      height: 22px;
+      border-radius: 50%;
+      background: #2d5ac5;
+      color: #fff;
+      display: inline-flex;
+      align-items: center;
+      justify-content: center;
+      font-size: 13px;
+      font-weight: 700;
+    }
+
+    .group-meta {
+      color: #7a8494;
+      font-size: 14px;
+      font-weight: 500;
+    }
 
-      &:last-child {
-        border-bottom: none;
+    .group-caret {
+      font-size: 12px;
+      color: #a6afbd;
+      transition: transform 0.2s ease;
+    }
+
+    .checklist-row {
+      &:first-of-type {
+        .checklist-item {
+          margin-top: 10px;
+        }
       }
+    }
 
-      input {
-        margin-right: 12px;
-        margin-top: 2px;
-        cursor: pointer;
-        flex-shrink: 0;
+    .checklist-item {
+      display: grid;
+      grid-template-columns: 22px minmax(0, 1fr);
+      gap: 10px;
+      align-items: flex-start;
+      width: calc(100% - 28px);
+      margin: 0 14px;
+      padding: 9px 14px;
+      border-radius: 7px;
+      background: #fff;
+
+      .item-index {
+        width: 22px;
+        height: 22px;
+        border-radius: 50%;
+        background: #e2e7ef;
+        color: #7f8da3;
+        display: inline-flex;
+        align-items: center;
+        justify-content: center;
+        font-size: 12px;
+        font-weight: 700;
+        line-height: 1;
+        margin-top: 1px;
+      }
+
+      .item-text {
+        font-size: 14px;
+        color: #4b5568;
+        line-height: 1.55;
       }
+    }
 
-      span {
+    .case-examples {
+      display: grid;
+      grid-template-columns: repeat(2, minmax(0, 1fr));
+      gap: 12px;
+      margin: 4px 14px 12px 46px;
+      padding: 12px;
+      border-radius: 8px;
+      background: #f8fafc;
+      border: 1px solid #e7ecf3;
+    }
+
+    .case-card {
+      min-width: 0;
+
+      .case-title {
         font-size: 13px;
-        color: #666;
-        line-height: 1.5;
+        font-weight: 700;
+        margin-bottom: 8px;
+      }
+
+      img {
+        width: 100%;
+        height: 220px;
+        display: block;
+        object-fit: contain;
+        border-radius: 6px;
+        border: 1px solid #e5eaf0;
+        background: #f6f8fb;
+      }
+
+      &.positive .case-title {
+        color: #16a34a;
       }
 
-      &.checked span {
-        text-decoration: line-through;
-        color: #999;
+      &.negative .case-title {
+        color: #dc2626;
+      }
+    }
+
+    @media (max-width: 1200px) {
+      .case-examples {
+        grid-template-columns: 1fr;
       }
     }
   }