Browse Source

feat: 火场文书

TwoKe 2 năm trước cách đây
mục cha
commit
195da8dbf3

BIN
src/assets/images/bg1.png


BIN
src/assets/images/bg2.png


BIN
src/assets/images/car-count-bg.png


BIN
src/assets/images/catch-border.png


BIN
src/assets/images/icon/fire-car-icon.png


BIN
src/assets/images/icon/people-icon.png


+ 117 - 2
src/views/detail/left/CatchInfo/index.vue

@@ -1,18 +1,133 @@
 <template>
   <ContainerBorder title="消防占道抓拍设备" pos="center">
-    <div>222</div>
+    <div class="catch-data">
+    <div class="catch-video">
+      <div class="current" style="display: flex; justify-content: center; align-items: center;">
+        当前选中的节点:{{currentNode}}
+      </div>
+      <div class="video-list">
+        <vue-seamless-scroll :data="listData" class="wrapper">
+          <div>
+            <div v-for="item in listData" class="video-item"
+            @click="checkNode({ id: item.id })" 
+            :class="{ active: isCurrent({ id: item.id }) }">
+              {{item.id}}
+            </div>
+          </div>
+        </vue-seamless-scroll>
+      </div>
+    </div>
+    <div class="catch-info">
+      <span class="catch-time">抓拍时间:2022.04.05 13:20:15</span>
+      <span class="catch-address">地&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;点:重庆市渝中区金汤街道81号</span>
+    </div>
+  </div>
   </ContainerBorder>
 </template>
 
 <script>
 import {ContainerBorder} from '@/components'
+import vueSeamlessScroll from 'vue-seamless-scroll'
 
 export default {
   components: {
-    ContainerBorder
+    ContainerBorder,
+    vueSeamlessScroll
+  },
+  data: () => ({
+    currentNode: 1,
+    listData: [{
+      id: 1,
+    }, {
+      id: 2
+    }, {
+      id: 3
+    }, {
+      id: 4
+    }]
+  }),
+  methods: {
+    checkNode(node) {
+      this.currentNode = node.id
+    },
+    isCurrent(node) {
+      return this.currentNode === node.id
+    }
   }
 }
 </script>
 
 <style lang="less" scoped>
+@import url("@/assets/styles/common.less");
+
+.catch-data {
+  margin: .45vh 0;
+  font-size: 17px;
+  color: #fff;
+
+  .catch-video {
+  padding: .45vh .25vw;
+  display: flex;
+  justify-content: space-between;
+
+
+  .current {
+    width: 12vw;
+    height: 20.7vh;
+    background-color: #00000060;
+    background: url("@/assets/images/catch-border.png") no-repeat;
+    background-size: 100% 100%;
+  }
+
+  
+
+  .video-list {
+    width: 7.8vw;
+    height: 20.7vh;
+    overflow: hidden;
+    .wrapper {
+      height: 20.7vh;
+      overflow: hidden;
+    }
+    .video-item {
+      margin-top: .9vh;
+      width: 7.8vw;
+      height: 9vh;
+      background-image:   linear-gradient(to right, #00000060 , #00000060);
+      transition: all .5s linear;
+      cursor: pointer;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      &:hover {
+        .active;
+      }
+    }
+    .active {
+        background-image:   linear-gradient(to right, #00000000 , #75faf660);
+      }
+  }
+}
+
+.catch-info {
+  flex: 1;
+  padding: 0px 0.4vw;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-around;
+  height: 4.65vh;
+  align-items: flex-start;
+  .catch-time {
+    color: #fff;
+    font-size: .7vw;
+  }
+
+  .catch-address {
+    color: #fff;
+    font-size: .7vw;
+  }
+
+}
+
+}
 </style>

+ 179 - 2
src/views/detail/right/DispatchPower/index.vue

@@ -1,6 +1,64 @@
 <template>
   <ContainerBorder title="出动力量">
-    <div>111</div>
+    <!-- 出动力量统计 -->
+    <div class="power-total">
+      <div class="total-item">
+        <img class="info-icon1" src="@/assets/images/icon/people-icon.png" alt="" />
+        <div class="info-data">
+          <div><span class="number">{{dispatchData['警力出动']}}</span><span class="unit">人</span></div>
+          <div class="label">警力出动</div>
+        </div>
+      </div>
+      <div class="total-item">
+        <img class="info-icon2" src="@/assets/images/icon/fire-car-icon.png"  alt="" />
+        <div class="info-data">
+          <div><span class="number">{{dispatchData['警车出动']}}</span><span class="unit">辆</span></div>
+          <div class="label">警车出动</div>
+        </div>
+      </div>
+    </div>
+    <!-- 人员信息 -->
+    <div class="people-info">
+      <div class="people-item">
+        <div class="name"> 王小强</div>
+        <div class="tag"> 辖区支队领导</div>
+        <div class="phone">15823887790</div>
+      </div>
+      <div class="people-item">
+        <div class="name"> 唐伯虎</div>
+        <div class="tag"> 带队干部</div>
+        <div class="phone">15823887790</div>
+      </div>
+      <div class="people-item">
+        <div class="name"> 朱小雄</div>
+        <div class="tag"> 值班领导</div>
+        <div class="phone">15823887790</div>
+      </div>
+    </div>
+    <!-- 车辆资源信息 -->
+    <div class="car-info">
+      <div class="car-item">
+        <div>
+          <span class="number">{{dispatchData['泡沫车(PM)']}}</span>
+          <span class="unit">辆</span>
+        </div>
+        <div class="label">泡沫车</div>
+      </div>
+      <div class="car-item">
+        <div>
+          <span class="number">{{dispatchData['水罐车(SG)']}}</span>
+          <span class="unit">辆</span>
+        </div>
+        <div class="label"> 水罐车</div>
+      </div>
+      <div class="car-item">
+        <div>
+          <span class="number">{{dispatchData['抢险救援车(JY)']}}</span
+          ><span class="unit">辆</span>
+        </div>
+        <div class="label"> 救援车</div>
+      </div>
+    </div>
   </ContainerBorder>
 </template>
 
@@ -10,9 +68,128 @@ import { ContainerBorder } from '@/components'
 export default {
   components: {
     ContainerBorder
-  }
+  },
+  data: () => ({
+    dispatchData: {
+      '警力出动': 36,
+      '警车出动': 9,
+      '泡沫车(PM)': 3,
+      '水罐车(SG)': 6,
+      '抢险救援车(JY)': 6,
+    }
+  })
 }
 </script>
 
 <style lang="less" scoped>
+@import url("@/assets/styles/common.less");
+@font-color: #75faf6;
+// 出动力量统计
+.power-total {
+  font-size: 17px;
+  color: #fff;
+  .flex(space-around);
+  .total-item {
+    .flex();
+    .info-icon1 {
+      margin-right: .5vw;
+      width: 55px;
+      height: 55px;
+    }
+    .info-icon2 {
+      margin-right: .5vw; 
+      width: 79px;
+      height: 61px;
+    }
+    .info-data {
+      .flex();
+      flex-direction: column;
+      .number {
+        position: relative;
+        font-size: 1.5vw;
+        font-weight: 900;
+        background-image: -webkit-linear-gradient(bottom,rgb(234, 163, 82),#ddc663); 
+        -webkit-background-clip: text; 
+        -webkit-text-fill-color: transparent;
+        &::after {
+          content: "";
+          position: absolute;
+          left: 50%;
+          width: 40%;
+          height: 80%;
+          display: inline-block;
+          background-image: -webkit-linear-gradient(bottom,rgba(234, 163, 82, .6),rgba(221, 198, 99, .6)); 
+          top: 10%;
+          filter: blur(1.1vh) brightness(100%) opacity(0.8);
+          transform: scale(0.95) translate(-50%);
+        }
+      }
+      .unit {
+        margin-left: .5vw;
+      }
+      .label {
+
+      }
+    }
+  }
+}
+// 人员信息
+.people-info { 
+  font-size: 17px;
+  color: #fff;
+  width: 100%;
+  .flex(space-around);
+  padding: .3vw 0vw;
+  .people-item {
+    .flex();
+    flex-direction: column;
+    .name {
+      padding: .3vh 0vw;
+      font-size: .74vw;
+      color: @font-color;
+    }
+
+    .tag {
+      width: 4.5vw;
+      background: #06466a;
+      border-radius: .1vw;
+      text-align: center;
+      padding: .2vh 0vw;
+      margin: .3vh 0vw;
+    }
+    
+    .phone {
+      color: @font-color;
+    }
+  }
+}
+// 车辆资源信息
+.car-info { 
+  font-size: 17px;
+  color: #fff;
+  width: 100%;
+  .flex(space-around);
+  .car-item {
+    .flex();
+    width: 5.3vw;
+    height: 6.7vh;
+    flex-direction: column;
+    background: url("@/assets/images/car-count-bg.png") no-repeat;
+    background-size: 100% 100%;
+    background-position: center center;
+    .number {
+      font-size: 1.5vw;
+      font-weight: 900;
+      color: #e0be5f;
+    }
+    .unit {
+      margin-left: .5vw;
+    }
+
+    .label {
+      font-size: .8vw;
+      font-weight: 400;
+    }
+  }
+}
 </style>

+ 155 - 0
src/views/detail/right/FireLog/LineModel.vue

@@ -0,0 +1,155 @@
+<template>
+  <div :id="moduleId" class="line-module">
+    <div class="line-module-bg">
+    <div class="dot" :style="{
+      boxShadow: `0 ${dotShadow1}vw ${dotShadow2}vw 0 rgba(73, 166, 182, 0.8)`,
+      backgroundColor: end ? '#65e7f6' : '#49a6b6'
+      }"></div>
+    <div :id="lineId" class="line"></div>
+    </div>
+    <div class="line-module-content">
+      <div class="content-prefix">
+        <div class="state">{{state}}</div>
+        <div class="time">{{time}}</div>
+      </div>
+      <div class="content-data">
+        <div class="text" v-if="!isImage">{{content}}</div>
+        <div class="img" v-else>
+          <img src="@/assets/images/bg1.png" />
+          <img src="@/assets/images/bg2.png" />
+        </div>
+      </div>
+      <div class="content-dept">{{dept}}</div>
+    </div>
+  </div>
+</template>
+
+<script>
+
+function guid() {
+  return 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+      var r = Math.random() * 16 | 0,
+          v = c == 'x' ? r : (r & 0x3 | 0x8);
+      return v.toString(16);
+  });
+}
+
+
+export default {
+  props: {
+    end: {
+      type: Boolean,
+      default: false
+    },
+    state: {
+      type: String,
+      default: ''
+    },
+    time: {
+      type: String,
+      default: ''
+    },
+    content: {
+      type: String,
+      default: ''
+    },
+    isImage: {
+      type: Boolean,
+      default: false
+    },
+    dept: {
+      type: String,
+      default: ''
+    }
+  },
+  data: () => ({
+    moduleId: `module-${guid()}`,
+    lineId: `line-${guid()}`,
+  }),
+  mounted() {
+    this.initLineHight();
+  },
+  computed : {
+    dotShadow1() {
+      return this.end ?  0.2 : 0;
+    },
+    dotShadow2() {
+      return this.end ? 0.6 : 0;
+    }
+  },
+  methods: {
+  /**
+   * 初始化线条的长度
+   */
+    initLineHight() {
+      if (this.end) return;
+      const moduleEl = document.getElementById(this.moduleId)
+      const lineEl = document.getElementById(this.lineId)
+      lineEl.style.height = `${moduleEl?.clientHeight - 5}px`
+    }
+  }
+}
+</script>
+
+<style scoped lang="less">
+@import url("@/assets/styles/common.less");
+@font-color: #75faf6;
+.line-module {
+  font-size: 17px;
+  color: #fff;
+  position: relative;
+  margin: 1.5vh 0px;
+  min-height: 9vh;
+  .line-module-bg {
+    position: absolute;
+    top: .8vh;
+    left: 0;
+    height: 1005;
+    .dot {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: .5vw;
+      height: .9vh;
+      border-radius: 50%;
+    }
+    .line {
+      position: absolute;
+      top: 1.5vh;
+      left: .16vw;
+      width: .1vw;
+      background-color: #49a6b650;
+      border-radius: .1vw;
+    }
+  }
+
+  .line-module-content {
+      padding: 0vh 1vw;
+    .content-prefix {
+      .flex(space-between, flex-end);
+      .state {
+        color: #e3b75c;
+        font-size: 1vw;
+      }
+    }
+    .content-data {
+      .text {
+        .ellipsis();
+        font-size: 14px;
+        color: @font-color;
+      }
+      .img {
+        .flex(flex-start);
+        img {
+          margin-right: .6vw;
+          width: 4.3vw;
+          height: 4.2vh;
+        }
+      }
+      padding: .9vh 0vw;
+      margin-bottom: .8vh;
+      border-bottom: .1vh solid #197bb5;
+    }
+  }
+}
+</style>

+ 43 - 6
src/views/detail/right/FireLog/index.vue

@@ -1,19 +1,56 @@
 <template>
   <ContainerBorder title="火场文书" pos="center">
-    <div>111</div>
+    <LineModel v-for="(item,index) in fireRecordData" :end="index === fireRecordData.length - 1" :key="index"
+      :state="item.state"
+      :time="item.time"
+      :isImage="item.isImage"
+      :content="item.content"
+      :dept="item.dept"
+    />
   </ContainerBorder>
 </template>
 
 <script>
 import { ContainerBorder } from '@/components'
-
-
-
+import LineModel from './LineModel'
 
 export default {
   components: {
-    ContainerBorder
-  }
+    ContainerBorder,
+    LineModel
+  },
+  data: () => ({
+    fireRecordData: [
+      {
+        state: '立案',
+        time: '2020-01-01 12:34',
+        content: '上午10点多,渝中区雅兰大厦9层冒出浓烟和火光, 从大厦里外围…… ',
+        dept: '渝中区公安局',
+        isImage: false
+      },
+      {
+        state: '出动',
+        time: '2020-01-01 12:34',
+        content: '上午10点多,渝中区雅兰大厦9层冒出浓烟和火光, 从大厦里外围…… ',
+        dept: '渝中区公安局',
+        isImage: false
+      },
+      {
+        state: '到场',
+        time: '2020-01-01 12:34',
+        content: '',
+        dept: '渝中区公安局',
+        isImage: true
+      },
+      {
+        state: '出水',
+        time: '2020-01-01 12:34',
+        content: '上午10点多,渝中区雅兰大厦9层冒出浓烟和火光, 从大厦里外围…… ',
+        dept: '渝中区公安局',
+        isImage: false
+      }
+    ]
+  })
 }
 </script>
 

+ 1 - 1
src/views/main/left/TodayIndustry/ListCard.vue

@@ -5,7 +5,7 @@
         <Card v-for="item in cardList" 
           :type="item.type"
         />
-    </div>
+      </div>
     </vue-seamless-scroll>
   </div>
 </template>