Просмотр исходного кода

Merge branch 'dev-bxy' into 'dev'

style: 修改灾害防范总览页面样式

See merge request product-group-fe/sfy-safety-group/sfy-safety!95
楼航飞 10 месяцев назад
Родитель
Сommit
96e1c66af4

+ 2 - 1
src/api/disaster-overview/index.ts

@@ -75,7 +75,7 @@ export interface TaskRecord {
 }
 export interface PreventInspectInfoRes {
   totalTask: number; // 总任务数
-  submittedTask: number; // 已提交任务数
+  submittedTask: number; // 待签字任务数
   signedTask: number; // 已签字任务数
   passTask: number; // 通过任务数
   dangerTask: number; // 隐患任务数
@@ -130,6 +130,7 @@ export const getDisasterHandleOverview = (params: QueryCheckingListsParams) => {
  * @description: 通知与管理规定(防御通知)
  */
 export interface NoticeAndRulesRes {
+  id: number; // 通知id
   title: string; // 通知标题
   createdBy: number; // 创建人id
   createdName: string; // 创建人姓名

BIN
src/assets/images/empty-2.png


+ 4 - 4
src/views/disaster/overview/PageOverview.vue

@@ -116,17 +116,17 @@
       }
 
       .bottom-box--right-item {
-        width: 70%;
+        width: calc(70% - 10px);
 
         .disaster-checking-lists {
-          height: 70%;
-          background-color: #fff;
+          height: 65%;
+          // background-color: #fff;
           border-radius: 4px;
           margin-bottom: 10px;
         }
 
         .notice-and-rules {
-          height: calc(30% - 10px);
+          height: calc(35% - 10px);
           background-color: #fff;
           border-radius: 4px;
         }

+ 306 - 42
src/views/disaster/overview/components/DisasterCheckingLists.vue

@@ -1,10 +1,64 @@
 <template>
   <div class="disaster-checking-lists-container">
-    <div class="container-title">
-      <span class="line"></span>
-      <span class="title">灾害预防检查及处置</span>
+    <div class="container-sums">
+      <div class="prevent-check">
+        <div class="container-title">
+          <span class="line"></span>
+          <span class="title">预防检查</span>
+        </div>
+        <div class="sum-data">
+          <div
+            v-for="(item, index) in preventCheckTitles"
+            :key="index"
+            class="sum-item"
+            :class="{
+              'warning-item': item.label === '隐患任务',
+              'success-item': item.label === '通过任务',
+            }"
+          >
+            <span class="item-count">{{ item.count }}</span>
+            <div class="item-title">
+              <div class="item-img-container">
+                <img class="item-img" :src="item.icon" alt="" />
+              </div>
+              <span class="item-label">{{ item.label }}</span>
+            </div>
+          </div>
+          <div class="more-info" @click="handleJumpToDetail('preventCheck')"
+            >查看详情<el-icon><DArrowRight /></el-icon
+          ></div>
+        </div>
+      </div>
+      <div class="disaster-handle">
+        <div class="container-title">
+          <span class="line"></span>
+          <span class="title">灾害处置</span>
+        </div>
+        <div class="sum-data">
+          <div
+            v-for="(item, index) in disasterHandleTitles"
+            :key="index"
+            class="sum-item"
+            :class="{
+              'loss-item': item.label === '有损失记录',
+              'success-item': item.label === '处置完成',
+            }"
+          >
+            <span class="item-count">{{ item.count }}</span>
+            <div class="item-title">
+              <div class="item-img-container">
+                <img class="item-img" :src="item.icon" alt="" />
+              </div>
+              <span class="item-label">{{ item.label }}</span>
+            </div>
+          </div>
+          <div class="more-info" @click="handleJumpToDetail('disasterHandle')"
+            >查看详情<el-icon><DArrowRight /></el-icon
+          ></div>
+        </div>
+      </div>
     </div>
-    <div class="checking-lists">
+    <!-- <div class="checking-lists">
       <div class="list-tabs">
         <div :class="activeTab === '预防检查' ? 'active-tab' : 'normal-tab'" @click="activeTab = '预防检查'"
           >预防检查</div
@@ -15,22 +69,129 @@
       </div>
       <DisasterCheckList class="list-container" v-if="activeTab === '预防检查'" />
       <DisasterDoneList class="list-container" v-if="activeTab === '灾害处置'" />
-    </div>
+    </div> -->
   </div>
 </template>
 
 <script setup lang="ts">
-  import { ref } from 'vue';
-  import DisasterCheckList from './disaster-checking-lists/DisasterCheckList.vue';
-  import DisasterDoneList from './disaster-checking-lists/DisasterDoneList.vue';
+  import { computed, onMounted, ref } from 'vue';
+  import { useRouter } from 'vue-router';
+  import { ElIcon } from 'element-plus';
+  import { DArrowRight } from '@element-plus/icons-vue';
+  import task from '@/assets/images/disaster-overview/task.png';
+  import signTask from '@/assets/images/disaster-overview/sign-task.png';
+  import successTask from '@/assets/images/disaster-overview/success-task.png';
+  import warningTask from '@/assets/images/disaster-overview/warning-task.png';
+  import brokenObject from '@/assets/images/disaster-overview/broken-object.png';
+  import {
+    QueryCheckingListsParams,
+    PreventInspectInfoRes,
+    getPreventInspect,
+    QueryDisasterHandleOverviewRes,
+    getDisasterHandleOverview,
+  } from '@/api/disaster-overview';
+  // import DisasterCheckList from './disaster-checking-lists/DisasterCheckList.vue';
+  // import DisasterDoneList from './disaster-checking-lists/DisasterDoneList.vue';
+
+  // const activeTab = ref('预防检查');<el-icon><Link /></el-icon>
+
+  const router = useRouter();
+
+  const queryCheckingListsParams = ref<QueryCheckingListsParams>({
+    pageNumber: 1,
+    pageSize: 3,
+  });
+  const preventInspectData = ref<PreventInspectInfoRes>();
+  const preventCheckTitles = computed(() => {
+    return [
+      {
+        icon: task,
+        label: '总任务',
+        count: preventInspectData.value?.totalTask,
+      },
+      {
+        icon: warningTask,
+        label: '隐患任务',
+        count: preventInspectData.value?.dangerTask,
+      },
+      {
+        icon: task,
+        label: '待签字任务',
+        count: preventInspectData.value?.submittedTask,
+      },
+      {
+        icon: successTask,
+        label: '通过任务',
+        count: preventInspectData.value?.passTask,
+      },
+      {
+        icon: signTask,
+        label: '已签字任务',
+        count: preventInspectData.value?.signedTask,
+      },
+    ];
+  });
 
-  const activeTab = ref('预防检查');
+  const disasterHandleData = ref<QueryDisasterHandleOverviewRes>();
+  const disasterHandleTitles = computed(() => {
+    return [
+      {
+        icon: signTask,
+        label: '应上报部门',
+        count: disasterHandleData.value?.dueReportDeptCount,
+      },
+      {
+        icon: brokenObject,
+        label: '有损失记录',
+        count: disasterHandleData.value?.lossRecordCount,
+      },
+      {
+        icon: signTask,
+        label: '已上报部门',
+        count: disasterHandleData.value?.completeReportDeptCount,
+      },
+      {
+        icon: successTask,
+        label: '处置完成',
+        count: disasterHandleData.value?.completeHandleCount,
+      },
+      {
+        icon: signTask,
+        label: '存在损失部门',
+        count: disasterHandleData.value?.existLossDeptCount,
+      },
+    ];
+  });
+
+  const handleJumpToDetail = (type: string) => {
+    if (type === 'preventCheck') {
+      router.push({
+        path: '/disaster-prevention/disaster-precaution/task-management',
+      });
+    } else if (type === 'disasterHandle') {
+      router.push({
+        path: '/disaster-prevention/disaster-control/disposal-management',
+      });
+    }
+    return;
+  };
+
+  const getData = async () => {
+    await getPreventInspect(queryCheckingListsParams.value).then((res) => {
+      preventInspectData.value = res;
+    });
+    await getDisasterHandleOverview(queryCheckingListsParams.value).then((res) => {
+      disasterHandleData.value = res;
+    });
+  };
+
+  onMounted(async () => {
+    getData();
+  });
 </script>
 
 <style scoped>
   .disaster-checking-lists-container {
-    padding: 10px 0;
-
     .container-title {
       display: flex;
       align-items: center;
@@ -50,51 +211,154 @@
       }
     }
 
-    .checking-lists {
-      height: calc(100% - 24px);
-      padding: 10px 20px;
+    .container-sums {
+      height: 100%;
       display: flex;
-      flex-direction: column;
-      overflow: auto;
+      align-items: center;
 
-      .list-tabs {
-        font-size: 14px;
-        cursor: pointer;
+      .prevent-check,
+      .disaster-handle {
+        width: 50%;
+        height: 100%;
         display: flex;
-        gap: 60px;
-        margin-bottom: 15px;
+        flex-direction: column;
+        background-color: #fff;
+        border-radius: 4px;
+        padding-top: 10px;
+      }
+
+      .prevent-check {
+        margin-right: 5px;
+      }
+
+      .disaster-handle {
+        margin-left: 5px;
+      }
+
+      .sum-data {
+        width: 100%;
+        height: 100%;
+        display: grid;
+        justify-content: center;
+        grid-template-columns: repeat(2, 50%);
+        grid-row-gap: 5px;
+        grid-column-gap: 5px;
+        padding: 10px;
+
+        .sum-item {
+          display: flex;
+          flex-direction: column;
+          align-items: center;
+          justify-content: space-evenly;
+          background: linear-gradient(180deg, rgba(227, 239, 255, 0.4) 0%, rgba(185, 209, 255, 0.38) 100%);
+          border-radius: 6px;
+          border-left: 5px solid rgba(23, 119, 255, 0.5);
+
+          .item-title {
+            display: flex;
+            align-items: center;
+          }
+
+          .item-img-container {
+            width: 20px;
+            height: 20px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            background-color: #fff;
+            border-radius: 50%;
+            margin-right: 6px;
+          }
 
-        .normal-tab {
-          color: rgba(0, 0, 0, 0.65);
+          .item-img {
+            width: 12px;
+          }
+
+          .item-label {
+            font-weight: 400;
+            font-size: 12px;
+            color: #666666;
+          }
+
+          .item-count {
+            font-weight: 600;
+            font-size: 20px;
+            color: #303133;
+          }
         }
 
-        .normal-tab:hover {
-          color: #1777ff;
+        .success-item {
+          background: linear-gradient(180deg, rgba(82, 196, 26, 0.15) 0%, rgba(82, 196, 26, 0.3) 100%);
+          border-left: 5px solid rgba(82, 196, 26, 0.5);
         }
 
-        .active-tab {
-          color: #1777ff;
-          font-weight: 600;
-          position: relative;
+        .warning-item {
+          background: linear-gradient(180deg, rgba(250, 173, 20, 0.15) 0%, rgba(250, 173, 20, 0.3) 100%);
+          border-left: 5px solid rgba(250, 173, 20, 0.5);
+        }
+
+        .loss-item {
+          background: linear-gradient(180deg, rgba(255, 77, 79, 0.15) 0%, rgba(255, 77, 79, 0.3) 100%);
+          border-left: 5px solid rgba(255, 77, 79, 0.5);
         }
 
-        .active-tab::after {
-          content: '';
-          display: block;
-          width: 16px;
-          height: 2px;
-          background-color: #1777ff;
-          border-radius: 2px;
-          margin-top: 2px;
-          position: absolute;
-          left: 50%;
-          transform: translateX(-50%);
+        .more-info {
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          font-size: 14px;
+          font-weight: 400;
+          color: #1777ff;
+          cursor: pointer;
         }
       }
+    }
+  }
+
+  .checking-lists {
+    height: calc(100% - 24px);
+    padding: 10px 20px;
+    display: flex;
+    flex-direction: column;
+    overflow: auto;
+
+    .list-tabs {
+      font-size: 14px;
+      cursor: pointer;
+      display: flex;
+      gap: 60px;
+      margin-bottom: 15px;
+
+      .normal-tab {
+        color: rgba(0, 0, 0, 0.65);
+      }
+
+      .normal-tab:hover {
+        color: #1777ff;
+      }
+
+      .active-tab {
+        color: #1777ff;
+        font-weight: 600;
+        position: relative;
+      }
 
-      .list-container {
-        flex: 1;
+      .active-tab::after {
+        content: '';
+        display: block;
+        width: 16px;
+        height: 2px;
+        background-color: #1777ff;
+        border-radius: 2px;
+        margin-top: 2px;
+        position: absolute;
+        left: 50%;
+        transform: translateX(-50%);
       }
     }
+
+    .list-container {
+      flex: 1;
+    }
   }
 </style>

+ 3 - 3
src/views/disaster/overview/components/KeyMonitorArea.vue

@@ -11,7 +11,7 @@
       </div>
       <div class="monitor-area">
         <div v-if="selectedCameras.length === 0" class="empty-style">
-          <img class="empty-img" src="@/assets/images/empty.png" alt="" />
+          <img class="empty-img" src="@/assets/images/empty-2.png" alt="" />
           <span>暂无监测区域</span>
         </div>
         <div v-for="(item, index) in selectedCameras" :key="index" class="monitor-item">
@@ -160,9 +160,9 @@
       padding: 16px 0;
       display: flex;
       flex-direction: column;
-      align-items: center;
 
       .add-area {
+        padding: 0 16px;
         display: flex;
         align-items: center;
         font-size: 14px;
@@ -248,7 +248,7 @@
           color: rgba(0, 0, 0, 0.5);
 
           .empty-img {
-            width: 80%;
+            width: 100%;
             object-fit: contain;
           }
         }

+ 42 - 5
src/views/disaster/overview/components/NoticeAndRules.vue

@@ -3,17 +3,17 @@
     <div class="container-title">
       <span class="line"></span>
       <span class="title">管理规定与通知</span>
+      <el-icon class="more" @click="handleJumpToMoreInfo"><DArrowRight /></el-icon>
     </div>
     <div class="notice-lists" v-loading="loading">
       <div v-if="noticeLists.length === 0" class="empty-style">
         <img class="empty-img" src="@/assets/images/empty.png" alt="" />
         <span>暂无数据</span>
       </div>
-      <div v-for="(item, index) in noticeLists" :key="index" class="notice-item">
+      <div v-for="(item, index) in noticeLists" :key="index" class="notice-item" @click="handleJumpToDetail(item.id)">
         <img src="@/assets/svg/bell.svg" alt="" />
         <div class="notice-title">{{ item.title }}</div>
         <div class="notice-info">
-          <span class="notice-issuer">发布人:{{ item.createdName }}</span>
           <span>{{ item.pushTime }}</span>
         </div>
       </div>
@@ -23,11 +23,31 @@
 
 <script lang="ts" setup>
   import { onMounted, ref } from 'vue';
+  import { useRouter } from 'vue-router';
+  import { ElIcon } from 'element-plus';
+  import { DArrowRight } from '@element-plus/icons-vue';
   import { NoticeAndRulesRes, getNoticeAndRules } from '@/api/disaster-overview';
 
+  const router = useRouter();
+
   const loading = ref(true);
   const noticeLists = ref<NoticeAndRulesRes[]>([]);
 
+  const handleJumpToMoreInfo = () => {
+    router.push({
+      path: '/disaster-prevention/disaster-warning/defense-notice',
+    });
+  };
+
+  const handleJumpToDetail = (id: number) => {
+    router.push({
+      path: '/disaster-prevention/disaster-warning/defense-notice-item',
+      query: {
+        id: id,
+      },
+    });
+  };
+
   onMounted(async () => {
     loading.value = true;
     noticeLists.value = await getNoticeAndRules();
@@ -58,6 +78,16 @@
       .title {
         margin-right: 12px;
       }
+
+      .more {
+        margin-left: auto;
+        margin-right: 10px;
+        cursor: pointer;
+        font-size: 14px;
+      }
+      .more:hover {
+        color: #1777ff;
+      }
     }
 
     .notice-lists {
@@ -72,6 +102,7 @@
       .notice-item {
         display: flex;
         align-items: center;
+        cursor: pointer;
 
         img {
           width: 18px;
@@ -80,8 +111,12 @@
         }
 
         .notice-title {
+          width: 60%;
           font-size: 14px;
           color: rgba(0, 0, 0, 0.85);
+          overflow: hidden;
+          white-space: nowrap;
+          text-overflow: ellipsis;
         }
 
         .notice-info {
@@ -89,10 +124,12 @@
           color: rgba(0, 0, 0, 0.45);
           margin-left: auto;
           display: flex;
+        }
+      }
 
-          .notice-issuer {
-            margin-right: 24px;
-          }
+      .notice-item:hover {
+        .notice-title {
+          color: #1777ff;
         }
       }
     }

+ 10 - 5
src/views/disaster/overview/components/WeatherCard.vue

@@ -63,12 +63,17 @@
       weatherInfo.value.warning = '';
       measureInfo.value = disasterMeasureDic.value.find((item) => item.itemCode === 'normal_measure')?.itemValue;
     } else {
-      const tempWarn = res[0].warnRecord[0];
-      if (tempWarn.warnTime.includes(dayjs().format('YYYY-MM-DD'))) {
+      const today = dayjs().format('YYYY-MM-DD');
+      const todayWarning = res[0].warnRecord.find((item) => item.warnTime.includes(today));
+      if (todayWarning) {
         weatherInfo.value.warning =
-          weatherDisasterDic.value.find((item) => item.itemCode === tempWarn.disasterType)?.itemValue || '';
-        const res = getWeatherWarningType(tempWarn.disasterType);
-        if (res) measureInfo.value = disasterMeasureDic.value.find((item) => item.itemCode.includes(res))?.itemValue;
+          weatherDisasterDic.value.find((item) => item.itemCode === todayWarning.disasterType)?.itemValue || '';
+        const res = getWeatherWarningType(todayWarning.disasterType);
+        if (res) {
+          measureInfo.value = disasterMeasureDic.value.find((item) => item.itemCode.includes(res))
+            ? disasterMeasureDic.value.find((item) => item.itemCode.includes(res))?.itemValue
+            : disasterMeasureDic.value.find((item) => item.itemCode === 'normal_measure')?.itemValue;
+        }
       } else {
         weatherInfo.value.warning = '';
         measureInfo.value = disasterMeasureDic.value.find((item) => item.itemCode === 'normal_measure')?.itemValue;

+ 1 - 0
src/views/disaster/overview/components/disaster-warning-records/RecordItem.vue

@@ -39,6 +39,7 @@
       display: flex;
       flex-direction: column;
       justify-content: space-between;
+      overflow: hidden;
 
       .info-title {
         font-weight: 500;

+ 1 - 0
src/views/disaster/overview/components/key-monitor-area/UpdateMonitorArea.vue

@@ -254,6 +254,7 @@
   }
 
   .el-dialog__body {
+    min-height: 500px;
     display: flex;
     justify-content: space-evenly;
   }