Sfoglia il codice sorgente

feat:新增安全巡查页面

yangqishu 4 mesi fa
parent
commit
e3815e15b0

BIN
src/assets/image/safety-inspection/search-bg.png


+ 1 - 1
src/store/home.store.js

@@ -1,7 +1,7 @@
 const homeStore = {
   //存储数据
   state: () => ({
-    mainMenu: "",
+    mainMenu: "综合概览",
   }),
   //修改数据
   mutations: {

+ 1 - 1
src/views/components/layerList/index.vue

@@ -145,7 +145,7 @@ export default {
 <style lang="scss" scoped>
 .layer-list-panel {
   position: absolute;
-  top: px-to-rem(100);
+  top: px-to-rem(80);
   left: px-to-rem(480);
   width: px-to-rem(240);
   padding: px-to-rem(10);

+ 5 - 1
src/views/index.vue

@@ -10,6 +10,8 @@
           <LayerListPanel></LayerListPanel>
           <SandMonitorLeft v-if="mainMenu === '采砂监控'"></SandMonitorLeft>
           <SandMonitorRight v-if="mainMenu === '采砂监控'"></SandMonitorRight>
+          <SafetyInspectionLeft v-if="mainMenu === '安全巡查'"></SafetyInspectionLeft>
+          <SafetyInspectionRight v-if="mainMenu === '安全巡查'"></SafetyInspectionRight>
           <ComprehensiveOverview v-if="mainMenu === '综合概览'"></ComprehensiveOverview>
         </div>
       </el-main>
@@ -24,11 +26,13 @@ import MainMap from '@/views/components/map'
 import LayerListPanel from '@/views/components/layerList'
 import SandMonitorLeft from './sand-monitor/left.vue'
 import SandMonitorRight from './sand-monitor/right.vue'
+import SafetyInspectionLeft from './safety-inspection/left.vue'
+import SafetyInspectionRight from './safety-inspection/right.vue'
 import ComprehensiveOverview from '@/views/comprehensive-overview/index'
 const basePathUrl = window.basePathUrl || ''
 export default {
   name: 'MainView',
-  components: { MainMap, LayerListPanel, menuPanel, SandMonitorLeft, SandMonitorRight, ComprehensiveOverview },
+  components: { MainMap, LayerListPanel, menuPanel, SandMonitorLeft, SandMonitorRight, SafetyInspectionLeft, SafetyInspectionRight, ComprehensiveOverview },
   computed: {
     ...mapState({
       mainMenu: (state) => state.home.mainMenu

+ 98 - 0
src/views/safety-inspection/left.vue

@@ -0,0 +1,98 @@
+<template>
+  <BasePanelLeft>
+    <div class="safety-inspection-left-container">
+      <base-header title="巡查记录"></base-header>
+      <div class="card-item">
+        <ul class="record-list">
+          <li class="record-list-item" v-for="(item, index) in recordList" :key="index">
+            <div class="record-title">{{ item.title }}</div>
+            <div class="record-content">
+              <div class="record-item">
+                <span>巡查开始时间:</span><span>{{ item.startTime }}</span>
+              </div>
+              <div class="record-item">
+                <span>巡查结束时间:</span><span>{{ item.endTime }}</span>
+              </div>
+              <div class="record-item" style="display: flex; justify-content: space-between">
+                <div>
+                  <span>巡查点位数:</span><span>{{ item.pointNum }}个</span>
+                </div>
+                <div>
+                  <span>巡查时长:</span><span>{{ item.duration }}</span>
+                </div>
+              </div>
+              <div class="record-item">
+                <span>巡查责任人:</span><span>{{ item.responsiblePerson }}</span>
+              </div>
+            </div>
+          </li>
+        </ul>
+      </div>
+    </div>
+  </BasePanelLeft>
+</template>
+<script>
+import BasePanelLeft from '@/components/base-panel/base-panel-left'
+import BaseHeader from '@/components/base-header/base-header'
+export default {
+  name: 'safetyInspectionLeft',
+  components: { BasePanelLeft, BaseHeader },
+  data() {
+    return {
+      recordList: Array(5).fill({
+        title: '一键巡河巡查任务名称1',
+        startTime: '2025-08-15 14:34:21',
+        endTime: '2025-08-15 16:32:34',
+        pointNum: 5,
+        duration: '2min',
+        responsiblePerson: '王刚'
+      })
+    }
+  },
+
+  methods: {}
+}
+</script>
+<style scoped lang="scss">
+@import url('@/assets/scss/px-to-rem.scss');
+.safety-inspection-left-container {
+  position: relative;
+  height: 100%;
+  z-index: 1;
+  .card-item {
+    position: relative;
+    width: 3.68rem;
+    padding: px-to-rem(10);
+    margin-bottom: px-to-rem(10);
+    background: url('@/assets/image/common/areaBg.png') no-repeat 0 0 / 100% 100%;
+  }
+  .record-list {
+    display: flex;
+    flex-direction: column;
+    padding: px-to-rem(10);
+    .record-list-item {
+      display: flex;
+      flex-direction: column;
+      margin-bottom: px-to-rem(10);
+      .record-title {
+        font-weight: bold;
+        font-size: px-to-rem(14);
+        color: #fff;
+        line-height: px-to-rem(30);
+      }
+      .record-content {
+        display: flex;
+        flex-direction: column;
+        border-bottom: 1px solid #5a80b4;
+        .record-item {
+          font-weight: 400;
+          font-size: px-to-rem(14);
+          color: #fff;
+          opacity: 0.8;
+          line-height: px-to-rem(30);
+        }
+      }
+    }
+  }
+}
+</style>

+ 255 - 0
src/views/safety-inspection/right.vue

@@ -0,0 +1,255 @@
+<template>
+  <base-panel-right>
+    <div class="safety-inspection-right-container">
+      <base-header title="一键巡河"></base-header>
+      <div class="card-item">
+        <div class="tools-panel">
+          <div class="btn add-btn"><i class="el-icon-plus"></i>&nbsp;新建任务</div>
+          <div class="input-bg">
+            <el-input v-model="taskName" size="mini" placeholder="搜索任务名称" suffix-icon="el-icon-search"></el-input>
+          </div>
+        </div>
+        <div class="task-list-container">
+          <ul class="task-table-list">
+            <li class="task-table-list-title">
+              <span>巡查任务</span>
+              <span>巡河次数</span>
+              <span>操作</span>
+            </li>
+            <li class="task-table-list-item" v-for="item in taskListData" :key="item.id">
+              <span>{{ item.taskName }}</span>
+              <span>{{ item.taskNum }}</span>
+              <span style="color: #498ee3; cursor: pointer">巡查</span>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <base-header title="预警联系人"></base-header>
+      <div class="card-item">
+        <div class="tools-panel" style="display: flex; align-items: center">
+          <el-select v-model="personStatus" size="mini">
+            <el-option label="在线" value="1"></el-option>
+            <el-option label="离线" value="2"></el-option>
+          </el-select>
+          <div class="input-bg">
+            <el-input v-model="personName" size="mini" placeholder="请输入名称" suffix-icon="el-icon-search"></el-input>
+          </div>
+        </div>
+        <div class="person-list-container">
+          <ul class="person-list">
+            <li class="person-list-item" v-for="item in personList" :key="item.id">
+              <div class="person-status" :class="{ on: item.status === '在线', off: item.status === '离线' }">{{ item.status }}</div>
+              <div class="line"></div>
+              <div class="person-info">
+                <div class="person-name">
+                  <span>{{ item.name }}</span>
+                  <span class="phone">{{ item.phone }}</span>
+                </div>
+                <div class="person-remark">{{ item.remark }}</div>
+              </div>
+              <div style="position: absolute; top: 0.04rem; right: 0.06rem">
+                <div class="btn details-btn" style="align-self: flex-start">详情</div>
+              </div>
+            </li>
+          </ul>
+        </div>
+      </div>
+    </div>
+  </base-panel-right>
+</template>
+<script>
+import BasePanelRight from '@/components/base-panel/base-panel-right'
+import BaseHeader from '@/components/base-header/base-header'
+export default {
+  name: 'sandMonitorRight',
+  components: { BasePanelRight, BaseHeader },
+  data() {
+    return {
+      taskName: '',
+      taskListData: [
+        { id: 1, taskName: '巡查任务名称1', taskNum: '1次' },
+        { id: 2, taskName: '巡查任务名称2', taskNum: '1次' },
+        { id: 3, taskName: '巡查任务名称3', taskNum: '1次' },
+        { id: 4, taskName: '巡查任务名称4', taskNum: '1次' },
+        { id: 5, taskName: '巡查任务名称5', taskNum: '1次' }
+      ],
+      personStatus: '1',
+      personName: '',
+      personList: [
+        {
+          id: 1,
+          status: '在线',
+          name: '杨英',
+          phone: '15319086888',
+          remark: '四乱(乱占、乱堆、乱采、乱建)'
+        },
+        {
+          id: 2,
+          status: '离线',
+          name: '马刚',
+          phone: '15191001567',
+          remark: '人员监控(下河、游泳、钓鱼、垃圾漂浮物等)'
+        },
+        {
+          id: 3,
+          status: '在线',
+          name: '马刚',
+          phone: '15191001567',
+          remark: '生态区监控'
+        },
+        {
+          id: 4,
+          status: '在线',
+          name: '谢智宇',
+          phone: '15319940131',
+          remark: '生态区监管'
+        }
+      ]
+    }
+  },
+
+  methods: {}
+}
+</script>
+<style scoped lang="scss">
+@import url('@/assets/scss/px-to-rem.scss');
+.safety-inspection-right-container {
+  position: relative;
+  height: 100%;
+  z-index: 1;
+  .card-item {
+    position: relative;
+    width: 3.68rem;
+    padding: px-to-rem(10);
+    margin-bottom: px-to-rem(10);
+    background: url('@/assets/image/common/areaBg.png') no-repeat 0 0 / 100% 100%;
+    :deep(.el-input__inner) {
+      background: transparent;
+      color: #fff;
+      border: none;
+    }
+  }
+  .tools-panel {
+    .input-bg {
+      margin: px-to-rem(10) 0;
+      background: url('@/assets/image/safety-inspection/search-bg.png') no-repeat 0 0 / 100% 100%;
+    }
+    :deep(.el-select) {
+      margin-right: px-to-rem(10);
+      .el-input__inner {
+        background: transparent;
+        border: 1px solid;
+        border-color: #4f9fff;
+        width: px-to-rem(100);
+        color: #fff;
+      }
+    }
+  }
+  .task-list-container {
+    .task-table-list {
+      &-title {
+        display: flex;
+        justify-content: space-between;
+        color: #f2f6ff;
+        font-size: px-to-rem(16);
+        padding: 0 px-to-rem(10);
+        height: px-to-rem(35);
+        line-height: px-to-rem(35);
+        background: #244e81;
+      }
+      &-item {
+        display: flex;
+        justify-content: space-between;
+        color: #fff;
+        font-size: px-to-rem(16);
+        padding: px-to-rem(4) px-to-rem(10);
+        margin-bottom: px-to-rem(1.8);
+        height: px-to-rem(35);
+        line-height: px-to-rem(35);
+        background: #153057;
+        box-sizing: border-box;
+      }
+    }
+  }
+
+  .person-list-container {
+    .person-list {
+      &-item {
+        position: relative;
+        display: flex;
+        justify-content: space-between;
+        height: px-to-rem(64);
+        border: 1px solid #0670b4;
+        border-radius: px-to-rem(50) 0 0 px-to-rem(50);
+        padding: px-to-rem(10);
+        margin-bottom: px-to-rem(20);
+        .person-status {
+          width: px-to-rem(41);
+          height: px-to-rem(41);
+          line-height: px-to-rem(41);
+          text-align: center;
+          padding: px-to-rem(2);
+          border-radius: 50%;
+          font-weight: bold;
+          font-size: px-to-rem(14);
+        }
+        .on {
+          background: rgba(13, 201, 133, 0.1);
+          border: 1px solid #0dc985;
+          color: #0dc985;
+        }
+        .off {
+          background: rgba(145, 158, 183, 0.1);
+          border: 1px solid #919eb7;
+          color: #919eb7;
+        }
+        .line {
+          width: px-to-rem(1);
+          height: px-to-rem(42);
+          background: #919eb7;
+          margin: 0 px-to-rem(10);
+        }
+        .person-info {
+          display: flex;
+          flex-direction: column;
+          flex: 1;
+          .person-name {
+            font-weight: bold;
+            font-size: px-to-rem(16);
+            color: #fff;
+            font-weight: 500;
+            margin-bottom: px-to-rem(5);
+            .phone {
+              margin-left: px-to-rem(15);
+              font-weight: bold;
+              font-size: px-to-rem(14);
+              color: #919eb7;
+            }
+          }
+          .person-remark {
+            font-size: px-to-rem(12);
+            color: #919eb7;
+            margin-bottom: px-to-rem(10);
+          }
+        }
+      }
+    }
+  }
+  .details-btn {
+    width: px-to-rem(36);
+    height: px-to-rem(22);
+  }
+  .add-btn {
+    width: px-to-rem(90);
+    height: px-to-rem(24);
+  }
+  .btn {
+    background: linear-gradient(0deg, #468adb 0%, #366dae 100%);
+    border-radius: px-to-rem(4);
+    border: px-to-rem(1) solid rgba(255, 255, 255, 0.8);
+    font-size: px-to-rem(14);
+    color: #ffffff;
+    text-align: center;
+  }
+}
+</style>

+ 5 - 4
src/views/sand-monitor/pie-chart/index.vue

@@ -39,10 +39,11 @@ export default {
         },
         legend: {
           orient: 'vertical',
-          left: 'right',
-          top: 'bottom',
-          itemGap: 10,
-          textStyle: { color: '#fff', fontSize: this.pxToRem(14) },
+          right: 10,
+          bottom: 0,
+          itemWidth: 12,
+          itemHeight: 6,
+          textStyle: { color: '#F5F5F5', fontSize: this.pxToRem(14) },
           formatter: (name) => {
             const item = this.seriesData.find((d) => d.name === name)
             return item ? `${name} ${item.value}` : name