xsh 3 lat temu
rodzic
commit
9f5d7de1b8

BIN
src/assets/BioSafety/box1111.png


BIN
src/assets/BioSafety/box2222.png


BIN
src/assets/BioSafety/scine1.png


BIN
src/assets/BioSafety/scine2.png


+ 62 - 0
src/components/TableFooter.vue

@@ -0,0 +1,62 @@
+<template>
+  <div style="margin-top: 20px; height: 50px">
+    <el-pagination background
+                   style="float: right; display: inline-block"
+                   :total="totals"
+                   layout="total, sizes, prev, pager, next, jumper"
+                   @size-change="sizeChange"
+                   @current-change="pageChange"
+                   :current-page.sync="pageNum"
+                   :page-sizes="sizesArray"
+                   :page-size="size"></el-pagination>
+  </div>
+</template>
+
+<script>
+  export default {
+    name: "TableFooter",
+    data() {
+      return {
+
+      }
+    },
+    props: {
+      totals: {
+        type: Number,
+        default() {
+          return 0;
+        },
+      },
+      sizesArray: {
+        type: Array,
+        default() {
+          return [10, 20, 40, 60, 80, 100];
+        },
+      },
+      size: {
+        type: Number,
+        default() {
+          return 20;
+        },
+      },
+      pageNum: {
+        type: Number,
+        default() {
+          return 1;
+        },
+      }
+    },
+    methods: {
+      sizeChange(value) {
+        this.$emit('sizeChange', value);
+      },
+      pageChange(value) {
+        this.$emit('pageChange', value);
+      },
+    }
+  }
+</script>
+
+<style scoped>
+
+</style>

Plik diff jest za duży
+ 166 - 0
src/components/newTable/NewTable.vue


+ 74 - 0
src/components/newTable/TableContent.vue

@@ -0,0 +1,74 @@
+<!--
+ * @Author: your name
+ * @Date: 2021-09-28 13:56:49
+ * @LastEditTime: 2021-12-21 14:32:04
+ * @LastEditors: Please set LastEditors
+ * @Description: In User Settings Edit
+ * @FilePath: \hyyfClient\src\components\newTable\TableContent.vue
+-->
+<template>
+  <div class="table-content">
+    <el-table
+      :data="listData"
+      border
+      :height="height"
+      @selection-change="handleSelectionChange"
+      :empty-text="emptyText"
+    >
+      <el-table-column v-if="shows.showSelect" type="selection" align="center">
+      </el-table-column>
+
+      <el-table-column
+        v-if="shows.showIndex"
+        type="index"
+        label="序号"
+        align="center"
+        width="70"
+      >
+      </el-table-column>
+
+      <template v-for="item in tableItems">
+        <el-table-column :key="item.prop" v-bind="item" align="center">
+          <template slot-scope="scope">
+            <slot :name="item.slotName" :row="scope.row">
+              {{ scope.row[item.prop] }}
+            </slot>
+          </template>
+        </el-table-column>
+      </template>
+    </el-table>
+  </div>
+</template>
+<script>
+export default {
+  props: {
+    listData: {
+      type: Array,
+      required: true,
+    },
+    height: {
+      // 表格高度控制
+      type: Number,
+      default: 500,
+    },
+    tableItems: {
+      type: Array,
+      required: true,
+    },
+    shows: {
+      type: Object,
+      default: () => ({ showIndex: true, showSelect: true }),
+    },
+    emptyText: {
+      type: String,
+      default: "暂无数据",
+    },
+  },
+  methods: {
+    handleSelectionChange(rows) {
+      this.$emit("selectionChange", rows);
+    },
+  },
+};
+</script>
+<style scoped></style>

+ 11 - 1
src/main.js

@@ -13,7 +13,7 @@ import store from './store'
 import 'lib-flexible/flexible'
 import './assets/ttf/font.css';
 import echart from 'echarts';
-import { DatePicker, Row, Col, Select, Option, Icon, Input, Button, Message, Cascader, Loading, Avatar } from 'element-ui';
+import { DatePicker, Row, Col, Select, Option, Icon, Input, Button, Message, Cascader, Loading, Avatar, Pagination, Table, TableColumn, Dialog, Switch, Empty, Tag } from 'element-ui';
 
 Vue.config.productionTip = false
 Vue.prototype.$echarts = echart
@@ -29,8 +29,18 @@ Vue.use(Message)
 Vue.use(Cascader)
 Vue.use(Loading)
 Vue.use(Avatar)
+Vue.use(Pagination)
+Vue.use(Table)
+Vue.use(TableColumn)
+Vue.use(Dialog)
+Vue.use(Switch)
+Vue.use(Empty)
+Vue.use(Tag)
 Vue.prototype.$message = Message;
 
+import { hasBtnPermission } from './utils/permission';
+Vue.prototype.hasPerm = hasBtnPermission
+
 new Vue({
   router,
   store,

+ 16 - 8
src/router/ChildrenRoutes.js

@@ -4,7 +4,8 @@ const childrenRouters = [
     name: 'Home',
     component: () => import('../views/Home/Home.vue'),
     meta: {
-      title: '青莲数智牧场驾驶舱'
+      title: '青莲数智牧场驾驶舱',
+      permission: 'home',
     }
   },
   {
@@ -12,7 +13,8 @@ const childrenRouters = [
     name: 'Home',
     component: () => import('../views/Home/Home.vue'),
     meta: {
-      title: '青莲数智牧场驾驶舱'
+      title: '青莲数智牧场驾驶舱',
+      permission: 'home',
     }
   },
   {
@@ -20,7 +22,8 @@ const childrenRouters = [
     name: 'BioSafety',
     component: () => import('../views/BioSafety/BioSafety.vue'),
     meta: {
-      title: '生物安全'
+      title: '生物安全',
+      permission: 'bioSafety',
     }
   },
   {
@@ -28,7 +31,8 @@ const childrenRouters = [
     name: 'Zoology',
     component: () => import('../views/Zoology/Zoology.vue'),
     meta: {
-      title: '生态监测'
+      title: '生态监测',
+      permission: 'zoology',
     }
   },
   {
@@ -36,7 +40,8 @@ const childrenRouters = [
     name: 'Production',
     component: () => import('../views/Production/Production.vue'),
     meta: {
-      title: '生产经营'
+      title: '生产经营',
+      permission: 'production',
     }
   },
   {
@@ -44,7 +49,8 @@ const childrenRouters = [
     name: 'Environment',
     component: () => import('../views/Environment/Environment.vue'),
     meta: {
-      title: '环境监测'
+      title: '环境监测',
+      permission: 'environment',
     }
   },
   {
@@ -52,7 +58,8 @@ const childrenRouters = [
     name: 'Alarm',
     component: () => import('../views/Alarm/Alarm.vue'),
     meta: {
-      title: '报警信息'
+      title: '报警信息',
+      permission: 'alarm',
     }
   },
   {
@@ -60,7 +67,8 @@ const childrenRouters = [
     name: 'Monit',
     component: () => import('../views/Monit/Monit.vue'),
     meta: {
-      title: '视频监控'
+      title: '视频监控',
+      permission: 'monit',
     }
   },
 ];

+ 33 - 2
src/store/index.js

@@ -1,6 +1,6 @@
 import Vue from 'vue'
 import Vuex from 'vuex'
-import { getFarm } from '../utils/api'
+import { getFarm, getMyButton } from '../utils/api'
 Vue.use(Vuex)
 
 export default new Vuex.Store({
@@ -14,6 +14,10 @@ export default new Vuex.Store({
       // 所选择的farmId
       farmId: '',
       farmList: [],
+      // 是否展示轮巡
+      screenVideo: false,
+      // 按钮权限
+      buttons: [],
   },
 
   mutations: {
@@ -28,7 +32,13 @@ export default new Vuex.Store({
     },
     SET_FARMLIST(state, data) {
       state.farmList = data;
-    }
+    },
+    SET_SCREENVIDEO(state, data) {
+      state.screenVideo = data;
+    },
+    SET_BUTTONS(state, data) {
+      state.buttons = data
+    },
   },
   actions: {
     setModeAsync(context, data) {
@@ -40,6 +50,24 @@ export default new Vuex.Store({
     setFarmIdAsync(context,data) {
       context.commit('SET_FARMID', data)
     },
+    setScreenVideoAsync(context,data) {
+      context.commit('SET_SCREENVIDEO', data)
+    },
+    // 获取用户按钮权限
+    GetButtons({ commit }) {
+      return new Promise((resolve, reject) => {
+        getMyButton({userId: localStorage.getItem('UserId')}).then(res => {
+          if(res.code === 10000) {
+            commit('SET_BUTTONS', res.data)
+            resolve(res.data)
+          } else {
+            reject(new Error(res.message))
+          }
+        }).catch(error => {
+          reject(error)
+        })
+      })
+    },
     // 获取牧场列表
     GetFarm({ commit }){
       return new Promise((resolve, reject) => {
@@ -57,5 +85,8 @@ export default new Vuex.Store({
     }
   },
   modules: {
+  },
+  getters: {
+    buttons: state => state.buttons
   }
 })

+ 37 - 0
src/utils/api.js

@@ -27,6 +27,15 @@ export function getFarm(data) {
   })
 }
 
+// 根据用户id 拿到默认的 颜色 和 导航栏
+export function findOne(data) {
+  return axios({
+    url: '/admin/accountMultilevel/findOne',
+    method: 'get',
+    params: data
+  })
+}
+
 // 根据id 修改 默认样式 导航
 export function findUpdate(data) {
   return axios({
@@ -388,3 +397,31 @@ export function InfoWeater(data) {
   })
 }
 
+
+// 拿到大屏按钮权限
+export function getMyButton(data) {
+  return axios({
+    url: '/admin/screen/auth/getMyButton',
+    method: 'get',
+    params: data
+  })
+}
+
+// 获取大屏菜单用户列表
+export function getUserMenuScreen(data) {
+  return axios({
+    url: '/admin/screen/auth/getMyMenu',
+    method: 'post',
+    params: data
+  })
+}
+
+// 设备列表
+export function getDeviceList(params) {
+  return axios({
+    url: '/admin/farm/device/listDevice',
+    method: 'get',
+    params: params
+  })
+}
+

+ 45 - 0
src/utils/chenApi.js

@@ -79,3 +79,48 @@ export function getWorkPlans(params) {
     params: params
   })
 }
+
+/* 车辆管理 - 车辆通行详情 */
+export function getCarPassage(data) {
+  return axios({
+    url: '/video/car/get_car_record',
+    method: 'get',
+    params: data
+  })
+}
+
+/** 报警详情 **/
+export function getCallDetail(data) {
+  return axios({
+    url: '/produce/warningInfo/listWarningInfoScreen',
+    method: 'post',
+    data: data
+  })
+}
+
+/*** 7天大门时间 **/
+export function gateSeven(data) {
+  return axios({
+    url: '/video/client/event/listEventBySort',
+    method: 'get',
+    params: data
+  })
+}
+
+// 数据查询
+export function getCarDrying(params) {
+  return axios({
+    url: '/video/telecom/listevent',
+    method: 'get',
+    params: params
+  })
+}
+// 温度变化
+export function getCarDryingTemp(params) {
+  return axios({
+    url: '/video/telecom/listeventdetail',
+    method: 'get',
+    params: params
+  })
+}
+

+ 7 - 0
src/utils/permission.js

@@ -0,0 +1,7 @@
+import store from '../store'
+
+export function hasBtnPermission(permission) {
+  const myBtns = store.getters.buttons
+  return myBtns.indexOf(permission) > -1
+}
+

+ 664 - 10
src/views/Alarm/Alarm.vue

@@ -12,7 +12,8 @@
             <div class="alarm-title-right"></div>
           </div>
           <div class="alarm-content" style="background: #0F152B">
-            <chart-pie v-if="alarmPie.length > 0" :data="alarmPie"></chart-pie>
+            <alarm-pie v-if="alarmPie.length > 0" :id="'0'" :text="'今日报警总量'" :pieData="alarmPie" @setOpen="openCall"></alarm-pie>
+<!--            <chart-pie v-if="alarmPie.length > 0" :data="alarmPie"></chart-pie>-->
             <div v-else style="line-height: 200px; font-size: 22px; color: white">暂无数据</div>
           </div>
         </div>
@@ -26,7 +27,7 @@
             <div class="alarm-title-right"></div>
           </div>
           <div class="alarm-content">
-            <alarm-bar :barData="list"></alarm-bar>
+            <alarm-bar :barData="list" @setOpen="setRank"></alarm-bar>
           </div>
         </div>
       </div>
@@ -86,7 +87,8 @@
             <div class="alarm-title-right"></div>
           </div>
           <div class="alarm-content">
-            <chart-pie v-if="pieData.length > 0" :text="'近7日事件总量'" :id="'1'" :data="pieData"></chart-pie>
+            <alarm-pie v-if="pieData.length > 0" :id="'1'" :text="'近7日事件总量'" :pieData="pieData" @setOpen="openEvent"></alarm-pie>
+<!--            <chart-pie v-if="pieData.length > 0" :text="'近7日事件总量'" :id="'1'" :data="pieData"></chart-pie>-->
             <div v-else style="line-height: 250px; text-align: center; width: 100%; font-size: 18px; color: white;">暂无数据</div>
           </div>
         </div>
@@ -100,7 +102,7 @@
             <div class="alarm-title-right"></div>
           </div>
           <div class="alarm-content">
-            <alarm-bar v-if="barData.salvProValue.length > 0" :bar-data="barData"></alarm-bar>
+            <alarm-bar v-if="barData.salvProValue.length > 0" :bar-data="barData" @setOpen="openEvent"></alarm-bar>
             <div v-else style="line-height: 250px; text-align: center; width: 100%; font-size: 18px; color: white;">暂无数据</div>
           </div>
         </div>
@@ -114,7 +116,7 @@
           <div class="alarm-title-right"></div>
         </div>
         <div class="alarm-content">
-          <div class="alarm-box">
+          <div class="alarm-box" @click="openDevice">
             <div class="box-item" v-for="(item, i) in devList" :key="i">
               <div class="box-bg">
                 <div class="box-absolute">{{item.value}}</div>
@@ -208,29 +210,205 @@
         </div>
       </div>
     </div>
+    <div class="bio-dialog" v-show="showDialog" @click="showDialog = false">
+      <div class="dialog-content3">
+        <div class="dialog-title">今日报警</div>
+        <div class="base-banner3">
+          <template v-if="callType === 0">
+            <template v-if="personList.length > 0 ">
+              <new-table v-if="callType === 0" :title="'报警列表'" :list-data="personList" :height="650" :table-items="personItem">
+                <template #recordImage="scope">
+                  <img :src="scope.row.recordImage" height="75px" alt="">
+                </template>
+                <template #name>
+                  <span>陌生人</span>
+                </template>
+              </new-table>
+            </template>
+            <template v-else>
+              <div style="text-align: center; color: white">暂无记录</div>
+            </template>
+          </template>
+          <template v-else>
+            <template v-if="listItem.length > 0">
+              <new-table  :title="'报警列表'" :list-data="listItem" :height="650" :table-items="tableItem">
+              </new-table>
+              <div @click.stop>
+                <table-footer :totals="total" :size="pageSize" @sizeChange="sizeChange" @pageChange="pageChange"></table-footer>
+              </div>
+            </template>
+            <template v-else>
+              <div style="text-align: center; color: white">暂无记录</div>
+            </template>
+          </template>
+
+        </div>
+      </div>
+    </div>
+    <div class="bio-dialog" v-show="eventDialog" @click="eventDialog = false">
+      <div class="dialog-content3">
+        <div class="dialog-title">事件分布</div>
+        <div class="base-banner3">
+          <template v-if="sort === 0">
+            <template v-if="sevenPersonList.length > 0">
+              <new-table  :title="'报警列表'" :list-data="sevenPersonList" :height="650" :table-items="personItem">
+                <template #recordImage="scope">
+                  <img :src="scope.row.recordImage" height="75px" alt="">
+                </template>
+                <template #name>
+                  <span>陌生人</span>
+                </template>
+              </new-table>
+            </template>
+            <template v-else>
+              <div  style="text-align: center; color: white">暂无记录</div>
+            </template>
+          </template>
+          <template v-else-if="sort === 2">
+            <div @click.stop>
+              <template v-if="gateList.length > 0">
+                <new-table  :title="'报警列表'" :list-data="gateList" :height="650" :table-items="gateItem">
+                  <template #alarmPicture="scope">
+                    <img :src="scope.row.imgUrl" height="75px" alt="">
+                  </template>
+                  <template #handler="scope">
+                    <el-button @click="playBack(scope.row)" size="mini">回放</el-button>
+                  </template>
+                </new-table>
+              </template>
+              <template v-else>
+                <div  style="text-align: center; color: white">暂无记录</div>
+              </template>
+            </div>
+            <div v-if="gateList.length > 0" @click.stop>
+              <table-footer :totals="gateTotal" :size="pageSize" @sizeChange="eventChange" @pageChange="eventPageChange"></table-footer>
+            </div>
+          </template>
+          <template v-else-if="sort === 3">
+            <div @click.stop>
+              <template v-if="gateList.length > 0">
+                <new-table  :title="'报警列表'" :list-data="gateList" :height="650" :table-items="sizhuItem">
+                  <template #alarmPicture="scope">
+                    <img :src="scope.row.imgUrl" height="75px" alt="">
+                  </template>
+                  <template #handler="scope">
+                    <el-button @click="playBack(scope.row)" size="mini">回放</el-button>
+                  </template>
+                </new-table>
+              </template>
+              <template v-else>
+                <div style="text-align: center; color: white">暂无记录</div>
+              </template>
+            </div>
+            <div @click.stop v-if="gateList.length > 0">
+              <table-footer :totals="gateTotal" :size="pageSize" @sizeChange="eventChange" @pageChange="eventPageChange"></table-footer>
+            </div>
+          </template>
+          <template v-else-if="sort === 4">
+            <div @click.stop>
+              <template v-if="carList.length > 0">
+                <new-table  :title="'报警列表'" :list-data="carList" :height="650" :table-items="carItem">
+                  <!-- 车辆烘干 -->
+                  <template #chekOk="scope">
+                    <span>{{ scope.row.chekOk === "1" ? "是" : "否" }}</span>
+                  </template>
+                  <template #handlerDrying="scope">
+                    <el-button @click="playEcharts(scope.row)" size="mini">查看本次烘干温度详情</el-button>
+                  </template>
+                </new-table>
+              </template>
+              <template v-else>
+                <div style="text-align: center; color: white">暂无记录</div>
+              </template>
+              <div @click.stop v-if="carList.length > 0">
+                <table-footer :totals="carTotal" :size="pageSize" @sizeChange="carChange" @pageChange="carPageChange"></table-footer>
+              </div>
+            </div>
+          </template>
+        </div>
+      </div>
+    </div>
+    <!-- 回放   -->
+    <el-dialog
+      width="60%"
+      :visible.sync="modalDevice"
+      :close-on-click-modal="false">
+      <iframe
+        :src="'static/dahua/index.html?' + rtsp"
+        frameborder="0"
+        style="width: 100%; height: 600px"
+      >
+      </iframe>
+    </el-dialog>
+    <el-dialog title="温度详情" :visible.sync="tempVisible" width="80%">
+      <div style="width: 100%; height: 500px">
+        <chart-car-drying :tempList="tempChartData"></chart-car-drying>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="tempVisible = false">取 消</el-button>
+        <el-button type="primary" @click="tempVisible = false">
+          确 定
+        </el-button>
+      </span>
+    </el-dialog>
+    <div class="bio-dialog" v-show="deviceShow" @click="deviceShow = false">
+      <div class="dialog-content3">
+        <div class="dialog-title">设备列表</div>
+        <div class="base-banner3">
+          <template v-if="deviceList.length > 0">
+            <new-table :height="650" :title="'设备列表'" :list-data="deviceList" :table-items="deviceItem">
+              <!-- table-col -->
+              <template #state="scope">
+                <el-tag
+                  size="small"
+                  :type="scope.row.state === 1 ? 'success' : 'danger'"
+                >
+                  {{ scope.row.state === 1 ? "正常" : "异常" }}
+                </el-tag>
+              </template>
+            </new-table>
+            <div @click.stop>
+              <table-footer :totals="deviceTotal" :size="pageSize" @sizeChange="devChange" @pageChange="devPageChange"></table-footer>
+            </div>
+          </template>
+          <template v-else>
+            <div style="text-align: center; color: white">暂无记录</div>
+          </template>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
 <script>
-import ChartPie from "@/views/Alarm/chart/ChartPie";
+// import ChartPie from "@/views/Alarm/chart/ChartPie";
 import AlarmBar from "@/views/Alarm/chart/AlarmBar";
 // import CostPie from "@/views/Alarm/chart/CostPie";
 // import ChartBar from "@/views/BioSafety/chart/ChartBar";
+import AlarmPie from "@/views/Alarm/chart/AlarmPie";
 import { swiper, swiperSlide } from 'vue-awesome-swiper'
 import 'swiper/css/swiper.css'
-import {getAlarmList, getWeekInfo, getPersonList, getAlarmRate, getCountByDay, getDevice} from "@/utils/api";
+import {getAlarmList, getWeekInfo, getPersonList, getAlarmRate, getCountByDay, getDevice, getCarWashVideo, getDeviceList } from "@/utils/api";
+import {gateSeven, getCallDetail, getCarDrying, getCarDryingTemp } from "@/utils/chenApi";
 import img from '@/assets/Alarm/111.png';
 import {timeDate} from "@/utils";
 import { mapState } from "vuex";
+import NewTable from "@/components/newTable/NewTable";
+import TableFooter from "@/components/TableFooter";
+import ChartCarDrying from "@/views/Alarm/chart/ChartCarDrying";
 
 export default {
   name: "Alarm",
   components: {
-    ChartPie,
+    // ChartPie,
     AlarmBar,
     // CostPie,
     swiper,
-    swiperSlide
+    swiperSlide,
+    AlarmPie,
+    NewTable,
+    TableFooter,
+    ChartCarDrying
   },
   data() {
     return {
@@ -297,6 +475,203 @@ export default {
           name: '设备异常率',
           value: '0'
         },
+      ],
+      callType: 1,
+      outPersonList: [],
+      pageNum: 1,
+      pageSize: 20,
+      total: 0,
+      listItem: [],
+      showDialog: false,
+      tableItem: [
+        {
+          prop: 'warningName',
+          label: '报警类型'
+        },
+        {
+          prop: 'warningTime',
+          label: '报警时间'
+        },
+        {
+          prop: 'levelName',
+          label: '报警等级',
+        },
+        {
+          prop: 'msg',
+          label: '报警内容',
+          minWidth: 200
+        }
+      ],
+      personItem: [
+        {
+          prop: 'swingTime',
+          label: '抓拍时间'
+        },
+        {
+          label: '抓拍图片',
+          slotName: 'recordImage'
+        },
+        {
+          label: '人员姓名',
+          slotName: 'name'
+        },
+        {
+          label: '抓拍区域',
+          prop: 'deviceName'
+        }
+      ],
+      sort: '',
+      gateList: [],
+      eventDialog: false,
+      gateItem: [
+        {
+          prop: 'alarmDate',
+          label: '时间',
+          minWidth: '150',
+          slotName: 'alarmDate'
+        },
+        {
+          prop: 'alarmPosition',
+          label: '地点',
+          minWidth: '100',
+          slotName: 'alarmPosition'
+        },
+        {
+          prop: 'alarmPicture',
+          label: '车辆图片',
+          minWidth: '150',
+          slotName: 'alarmPicture'
+        },
+        {
+          prop: 'alarmTypeName',
+          label: '类型',
+          minWidth: '150',
+          slotName: 'alarmTypeName'
+        },
+        {
+          label: '操作',
+          minWidth: '150',
+          slotName: 'handler'
+        }
+      ],
+      gateTotal: 0,
+      modalDevice: false,
+      rtsp: '',
+      sizhuItem: [
+        {
+          prop: 'alarmDate',
+          label: '时间',
+          minWidth: '150',
+          slotName: 'alarmDate'
+        },
+        {
+          prop: 'alarmPosition',
+          label: '地点',
+          minWidth: '100',
+          slotName: 'alarmPosition'
+        },
+        {
+          prop: 'alarmPicture',
+          label: '死猪图片',
+          minWidth: '150',
+          slotName: 'alarmPicture'
+        },
+        {
+          prop: 'alarmTypeName',
+          label: '类型',
+          minWidth: '150',
+          slotName: 'alarmTypeName'
+        },
+        {
+          label: '操作',
+          minWidth: '150',
+          slotName: 'handler'
+        }
+      ],
+      sevenPersonList: [],
+      sevenItem: [],
+      personTotal: 0,
+      carList: [],
+      carItem: [
+        {
+          prop: 'eventTime',
+          label: '发生时间',
+          minWidth: '150',
+          slotName: 'eventTime'
+        },
+        {
+          prop: 'location',
+          label: '发生地点',
+          minWidth: '150',
+          slotName: 'location'
+        },
+        {
+          prop: 'chekOk',
+          label: '烘干是否达标',
+          minWidth: '150',
+          slotName: 'chekOk'
+        },
+        {
+          label: '操作',
+          minWidth: '150',
+          slotName: 'handlerDrying'
+        }
+      ],
+      carTotal: 0,
+      tempVisible: false,
+      tempChartData: {},
+      deviceShow: false,
+      deviceList: [],
+      deviceTotal: 0,
+      deviceItem: [
+        {
+          prop: "deviceName",
+          label: "设备名称",
+          minWidth: 100,
+          slotName: "deviceName",
+        },
+        {
+          prop: "deviceCode",
+          label: "设备编号",
+          minWidth: 100,
+          slotName: "deviceCode",
+        },
+        {
+          prop: "deviceType",
+          label: "型号",
+          minWidth: 100,
+          slotName: "deviceType",
+        },
+        {
+          prop: "factory",
+          label: "厂家",
+          minWidth: 100,
+          slotName: "factory",
+        },
+        {
+          prop: "worker",
+          label: "维保人",
+          minWidth: 100,
+          slotName: "worker",
+        },
+        {
+          prop: "mainParams",
+          label: "基本参数",
+          minWidth: 120,
+          slotName: "mainParams",
+        },
+        {
+          prop: "state",
+          label: "状态",
+          minWidth: 120,
+          slotName: "state",
+        },
+        {
+          prop: "record",
+          label: "维修记录",
+          minWidth: 120,
+          slotName: "record",
+        },
       ]
     }
   },
@@ -304,6 +679,38 @@ export default {
     ...mapState(['ip'])
   },
   methods: {
+    devChange(val) {
+      this.pageSize = val;
+      this.initDev()
+    },
+    devPageChange(val) {
+      this.pageNum = val;
+      this.initDev()
+    },
+    sizeChange(val) {
+      this.pageSize = val;
+      this.initAlarm()
+    },
+    pageChange(val) {
+      this.pageNum = val;
+      this.initAlarm();
+    },
+    eventChange(val) {
+      this.pageSize = val;
+      this.initEvent()
+    },
+    eventPageChange(val) {
+      this.pageNum = val;
+      this.initEvent();
+    },
+    carChange(val) {
+      this.pageSize = val;
+      this.initCar()
+    },
+    carPageChange(val) {
+      this.pageNum = val;
+      this.initCar();
+    },
     alarmClick(num) {
       this.num = num;
       if(num === 1) {
@@ -485,7 +892,6 @@ export default {
               this.barData.salvProValue.push(item.value);
             })
             this.pieData = res.data;
-            console.log(this.pieData);
           }
           this.pieLoading = false;
         } else {
@@ -509,6 +915,189 @@ export default {
       this.dialog = true;
       this.selectImg = item.recordImage;
       this.selectItems = item;
+    },
+    openCall(val) {
+      this.pageNum = 1;
+      this.listItem = [];
+      this.showDialog = true;
+      let name = val.name;
+      switch (name) {
+        case '生态监测':
+          this.callType = 1;
+          this.initAlarm();
+          break;
+        case '环境监测':
+          this.callType = 2;
+          this.initAlarm();
+          break;
+        case '人员违规':
+          this.callType = 0;
+          break;
+        default:
+          return
+      }
+    },
+
+    setRank(val) {
+      this.pageNum = 1;
+      this.listItem = [];
+      this.showDialog = true;
+      let name = val.name;
+      switch (name) {
+        case '一级':
+          this.callType = 3;
+          break;
+        case '二级':
+          this.callType = 4;
+          break;
+        case '三级':
+          this.callType = 5;
+          break;
+        default:
+          return
+      }
+      this.initAlarm()
+    },
+    initAlarm() {
+      let params= {
+        type: this.callType,
+        current: this.pageNum,
+        size: this.pageSize
+      }
+      getCallDetail(params).then(res => {
+        if(res.code === 10000) {
+          this.listItem = res.data.records;
+          this.total = res.data.total;
+        }
+      })
+    },
+    openEvent(val) {
+      this.eventDialog = true;
+      let name = val.name;
+      this.pageNum = 1;
+      switch (name) {
+        case '车辆洗消':
+          this.sort = 2;
+          this.initEvent()
+          break;
+        case '死猪运输':
+          this.sort = 3;
+          this.initEvent()
+          break;
+        case '人员违规':
+          this.sort = 0;
+          this.sevenPerson()
+          break;
+        case '车辆烘干':
+          this.sort = 4;
+          this.initCar();
+          break;
+        default:
+          return
+      }
+    },
+    initEvent() {
+      let endTime = timeDate(new Date().getTime());
+      let startTime = timeDate(new Date().getTime() - 1000 * 60 * 60 * 24 * 7);
+
+      let params = {
+        alarmStartDateString: startTime + ' 00:00:00',
+        alarmEndDateString: endTime + ' 00:00:00',
+        pageNum: this.pageNum,
+        pageSize: this.pageSize,
+        sort: this.sort,
+      }
+      gateSeven(params).then(res => {
+        if(res.code === 0) {
+          const result = JSON.parse(res.data.result);
+          this.gateList = result.data.pageData;
+          this.gateTotal = parseInt(res.total);
+          this.gateList.forEach(item => {
+            item.imgUrl = `${this.ip}/video/picture/get?alarmPicture=${item.alarmPicture}`
+          })
+        }
+      })
+    },
+    playBack(item) {
+      this.modalDevice = true
+      getCarWashVideo({
+        happendTime: item.alarmDate,
+        channelName: item.alarmPosition,
+      }).then(res => {
+        if (res.code === 0) {
+          this.rtsp = res.URL;
+          this.videoVisible = true;
+        }
+      })
+    },
+    // 7天人员违规
+    sevenPerson() {
+      let endTime = timeDate(new Date().getTime());
+      let startTime = timeDate(new Date().getTime() - 1000 * 60 * 60 * 24 * 7);
+      let params = {
+        pageNum: this.pageNum,
+        pageSize: this.pageSize,
+        startSwingTime: startTime + ' 00:00:00',
+        endSwingTime: endTime + ' 00:00:00',
+        containDomain: 1,
+        openResult: 0
+      }
+      getPersonList(params).then(async res => {
+        if(res.code == 0) {
+          let result = JSON.parse(res.result);
+          this.sevenPersonList = result.data.pageData;
+          // const { token } = await getFaceToken();
+          this.sevenPersonList.forEach((item) => {
+            item.channelName = item.channelName.split("人脸门禁")[0];
+            item.recordImage = `${this.ip}/video/picture/get?alarmPicture=${item.recordImage}`;
+            // item.recordImage = `https://36.26.62.70:447/evo-pic/${item.recordImage}?token=${token}&oss_addr=172.16.3.223:8925`;
+          });
+        }
+      })
+    },
+    // 车辆烘干
+    initCar() {
+      let endTime = timeDate(new Date().getTime());
+      let startTime = timeDate(new Date().getTime() - 1000 * 60 * 60 * 24 * 7);
+      getCarDrying({
+        startTimeString: startTime + " 00:00:00",
+        endTimeString: endTime + " 23:59:59",
+        current: this.pageNum,
+        size: this.pageSize,
+      }).then((res) => {
+        if (res && res.code === 10000) {
+          this.carList = res.data.records;
+          this.carTotal = res.data.total;
+        }
+      });
+    },
+    playEcharts(row) {
+      getCarDryingTemp({
+        deviceId: row.deviceId,
+        eventTimeString: row.eventTime,
+      }).then((res) => {
+        if (res.code === 10000) {
+          this.tempChartData = res.data;
+          this.tempVisible = true;
+        }
+      });
+    },
+    openDevice() {
+      this.deviceShow = true;
+      this.pageNum = 1;
+      this.initDev();
+    },
+    initDev() {
+      let params = {
+        pageNo: this.pageNum,
+        pageSize: this.pageSize
+      }
+      getDeviceList(params).then(res => {
+        if (res.code === 10000) {
+          this.deviceList = res.data.content;
+          this.deviceTotal = res.data.totalElements;
+        }
+      })
     }
   },
   mounted() {
@@ -519,6 +1108,46 @@ export default {
 </script>
 
 <style scoped>
+  /deep/.el-pagination__total {
+    color: #fff
+  }
+  /deep/.el-table th.el-table__cell {
+    background-color: #009cff !important;
+    color: white;
+  }
+  /deep/.el-table tr {
+    background-color: rgba(0, 0, 205, .8);
+    color: #fff;
+  }
+  /deep/.el-table--enable-row-hover .el-table__body tr:hover>td.el-table__cell {
+    color: #009cff;
+  }
+  /deep/.el-table--scrollable-y .el-table__body-wrapper::-webkit-scrollbar {
+    /*滚动条整体样式*/
+    width : 5px;  /*高宽分别对应横竖滚动条的尺寸*/
+    height: 1px;
+  }
+  /deep/.el-table--scrollable-y .el-table__body-wrapper::-webkit-scrollbar-thumb {
+    /*滚动条里面小方块*/
+    border-radius   : 8px;
+    background-color:  #535353;
+    background-image: -webkit-linear-gradient(
+      45deg,
+      rgba(255, 255, 255, 0.2) 25%,
+      transparent 25%,
+      transparent 50%,
+      rgba(255, 255, 255, 0.2) 50%,
+      rgba(255, 255, 255, 0.2) 75%,
+      transparent 75%,
+      transparent
+    );
+  }
+  /deep/.el-table--scrollable-y .el-table__body-wrapper::-webkit-scrollbar-track {
+    /*滚动条里面轨道*/
+    box-shadow   : inset 0 0 5px rgba(0, 0, 0, 0.2);
+    /*background   : #ededed;*/
+    border-radius: 10px;
+  }
   .alarm {
     width: 100%;
     height: 100%;
@@ -757,6 +1386,7 @@ export default {
     width: 100%;
     height: 100%;
     display: flex;
+    cursor: pointer;
   }
   .box-item {
     flex: 1;
@@ -794,6 +1424,21 @@ export default {
 
     /*background-color: black;*/
   }
+  .dialog-content3 {
+    width: 1400px;
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+  }
+  .dialog-title {
+    color: white;
+    font-size: 16px;
+    position: absolute;
+    top: -10px;
+    left: 50%;
+    transform: translate(-50%, 0);
+  }
   .base-banner1 {
     width: 800px;
     height: 600px;
@@ -824,4 +1469,13 @@ export default {
     text-align: left;
     padding-left: 50px;
   }
+  .base-banner3 {
+    width: 1400px;
+    height: 800px;
+    box-sizing: border-box;
+    padding: 40px 40px 20px 50px;
+    align-items: center;
+    background: url("../../assets/BioSafety/box2222.png") no-repeat;
+    background-size: 100% 100%;
+  }
 </style>

+ 3 - 0
src/views/Alarm/chart/AlarmBar.vue

@@ -135,6 +135,9 @@ export default {
         ]
       }
       this.myChart.setOption(options);
+      this.myChart.on('click', function (params) {
+        that.$emit('setOpen', params)
+      })
     },
   },
   mounted() {

+ 173 - 0
src/views/Alarm/chart/AlarmPie.vue

@@ -0,0 +1,173 @@
+<template>
+  <div :id="'alarm-pie' + id" style="width: 100%; height: 100%"></div>
+</template>
+
+<script>
+export default {
+  name: "AlarmPie",
+  data() {
+    return {
+      myChart: null,
+    };
+  },
+  props: {
+    id: {
+      type: String,
+      default: () => '0',
+    },
+    text: {
+      type: String,
+      default: () => '今日报警总量'
+    },
+    pieData: {
+      type: Array,
+      default: () => [],
+    },
+  },
+  methods: {
+    init() {
+      let title = this.text;
+      let color = [
+        "#0E7CE2",
+        "#FF8352",
+        "#E271DE",
+        "#F8456B",
+        "#00FFFF",
+        "#4AEAB0",
+      ];
+      // let echartData = [
+      //   {
+      //     name: "环境报警",
+      //     value: "3720",
+      //   },
+      //   {
+      //     name: "人员违规",
+      //     value: "2920",
+      //   },
+      //   {
+      //     name: "环境监测",
+      //     value: "2200",
+      //   },
+      //   {
+      //     name: "污水排放",
+      //     value: "1420",
+      //   },
+      //   {
+      //     name: "设备异常",
+      //     value: "1420",
+      //   },
+      // ];
+      let echartData = this.pieData;
+      let formatNumber = function(num) {
+        let reg = /(?=(\B)(\d{3})+$)/g;
+        return num.toString().replace(reg, ",");
+      };
+      let total = echartData.reduce((a, b) => {
+        return a + b.value * 1;
+      }, 0);
+      let options = {
+        title: [
+          {
+            text:
+              "{name|" + title + "}\n{val|" + formatNumber(total) + "} " + "条",
+            top: "center",
+            left: "35%",
+            textStyle: {
+              rich: {
+                name: {
+                  fontSize: 14,
+                  fontWeight: "normal",
+                  color: "#fff",
+                  padding: [10, 0],
+                  textAlign: "center",
+                },
+                val: {
+                  fontSize: 32,
+                  fontWeight: "bold",
+                  color: "#fff",
+                },
+              },
+            },
+          },
+        ],
+        color: color,
+        tooltip: {
+          trigger: "item",
+          formatter: function(parms) {
+            var str =
+              parms.marker +
+              "" +
+              parms.data.name +
+              "</br>" +
+              "数量:" +
+              parms.data.value +
+              "条" +
+              "</br>" +
+              "占比:" +
+              parms.percent +
+              "%";
+            return str;
+          },
+        },
+        // legend: {
+        //   orient: "vertical",
+        //   left: "65%",
+        //   align: "left",
+        //   top: "middle",
+        //   icon: "circle",
+        //   itemGap: 20,
+        //   textStyle: {
+        //     color: "#8C8C8C",
+        //   },
+        // },
+        series: [
+          {
+            type: "pie",
+            radius: ["60%", "75%"],
+            center: ["50%", "50%"],
+            data: echartData,
+            hoverAnimation: false,
+            itemStyle: {
+              normal: {
+                borderColor: "#fff",
+                borderWidth: 5,
+              },
+            },
+          },
+        ],
+      };
+      this.myChart.setOption(options);
+      let that = this;
+      this.myChart.on('click', function (params) {
+        that.$emit('setOpen', params)
+      })
+    },
+  },
+  mounted() {
+    this.myChart = this.$echarts.init(document.getElementById("alarm-pie" + this.id));
+    this.init();
+    let that = this;
+    // 监听resize
+    window.addEventListener("resize", function() {
+      that.myChart.resize();
+    });
+  },
+  watch: {
+    color(newVal) {
+      if (newVal) {
+        this.myChart.clear();
+        this.init();
+      }
+    },
+    pieData: {
+      handler(newVal) {
+        console.log(newVal);
+        this.myChart.clear();
+        this.init();
+      },
+    },
+  },
+};
+</script>
+
+<style scoped></style>

+ 155 - 0
src/views/Alarm/chart/ChartCarDrying.vue

@@ -0,0 +1,155 @@
+<!--
+ * @Author: your name
+ * @Date: 2021-12-05 16:50:40
+ * @LastEditTime: 2021-12-05 17:01:00
+ * @LastEditors: Please set LastEditors
+ * @Description: 车辆管理 - 车辆烘干 - 温度详情图
+ * @FilePath: \hyyfClient\src\views\BioSafety\chart\ChartCarDrying.vue
+-->
+<template>
+  <div id="chart-car-dring" style="width: 100%; height: 100%"></div>
+</template>
+
+<script>
+import { mapState } from "vuex";
+export default {
+  name: "ChartPigTemp",
+  computed: {
+    ...mapState(["color"]),
+  },
+  data() {
+    return {
+      myChart: null,
+    };
+  },
+  props: {
+    tempList: {
+      type: Object,
+      default: function() {
+        return {
+          timeList: [],
+          tempList: [],
+        };
+      },
+    },
+  },
+  watch: {
+    color(newVal) {
+      if (newVal) {
+        this.myChart.clear();
+        this.init();
+      }
+    },
+    tempList: {
+      handler(newVal) {
+        if (newVal) {
+          this.myChart.clear();
+          this.init();
+        }
+      },
+      deep: true,
+    },
+  },
+  methods: {
+    init() {
+      let start = 0;
+      let end = this.tempList.timeList.length - 1;
+      let time = this.tempList.timeList;
+      let data = this.tempList.tempList;
+      // let name = this.tempList.name;
+      // this.tempList.list.forEach((item) => {
+      //   time.push(item.createTime);
+      //   data.push(item.value);
+      // });
+      let options = {
+        // title: {
+        //   text: `${name}温度曲线`,
+        //   left: "center",
+        // },
+        tooltip: {
+          trigger: "axis",
+        },
+        color: [this.color],
+        dataZoom: [
+          {
+            type: "inside",
+            startValue: start,
+            endValue: end,
+            show: false,
+          },
+        ],
+        xAxis: [
+          {
+            type: "category",
+            data: time,
+            axisPointer: {
+              type: "shadow",
+            },
+            axisLine: {
+              show: false,
+              lineStyle: {
+                color: "#6e7079",
+              },
+            },
+            axisTick: {
+              show: false,
+            },
+          },
+        ],
+        yAxis: [
+          {
+            type: "value",
+            // name: "温度统计情况",
+            axisLabel: {
+              formatter: "{value}℃",
+            },
+            axisLine: {
+              show: false,
+              lineStyle: {
+                color: "#6e7079",
+              },
+            },
+            axisTick: {
+              show: false,
+            },
+          },
+        ],
+        series: [
+          {
+            name: `${name}`,
+            type: "line",
+            // stack: 'Total',
+            smooth: true,
+            areaStyle: {},
+            emphasis: {
+              focus: "series",
+            },
+            itemStyle: {
+              color: this.color,
+              borderColor: this.color,
+              normal: {
+                label: {
+                  show: true,
+                  textStyle: {
+                    fontSize: 14,
+                  },
+                },
+              },
+            },
+            data: data,
+          },
+        ],
+      };
+      this.myChart.setOption(options);
+    },
+  },
+  mounted() {
+    this.myChart = this.$echarts.init(
+      document.getElementById("chart-car-dring")
+    );
+    this.init();
+  },
+};
+</script>
+
+<style scoped></style>

Plik diff jest za duży
+ 800 - 12
src/views/BioSafety/BioSafety.vue


+ 22 - 14
src/views/BioSafety/chart/ChartBar.vue

@@ -40,7 +40,7 @@ export default {
       let max = Math.max(...this.data.data);
       let max1 = max * 1.2;
       // 获取当前数组的数量并push 成新数组
-      let data1 = new Array(this.data.data.length).fill(max1);
+      // let data1 = new Array(this.data.data.length).fill(max1);
       let options = {
         // tooltip: {
         //   trigger: "axis",
@@ -81,6 +81,7 @@ export default {
               width: "2", //坐标线的宽度
             },
           },
+          max: max1,
           axisLabel: {
             formatter: `{value}${this.data.unit}`,
             textStyle: {
@@ -118,22 +119,29 @@ export default {
             symbolMargin: 3,
             data: this.data.data,
           },
-          {
-            type: "pictorialBar",
-            symbol: "rect",
-            itemStyle: {
-              color: "#022a62",
-              barBorderRadius: 3,
-            },
-            symbolRepeat: true,
-            symbolSize: [20, 3],
-            symbolMargin: 3,
-            z: -10,
-            data: data1,
-          },
+          // {
+          //   type: "pictorialBar",
+          //   symbol: "rect",
+          //   itemStyle: {
+          //     color: "#022a62",
+          //     barBorderRadius: 3,
+          //   },
+          //   symbolRepeat: true,
+          //   symbolSize: [20, 3],
+          //   symbolMargin: 3,
+          //   z: -10,
+          //   data: data1,
+          // },
         ],
       }
       this.myChart.setOption(options)
+      let that = this;
+      this.myChart.on('click', function (params){
+        console.log(params)
+        if(params.value !== max1) {
+          that.$emit('setOpen', params.name)
+        }
+      })
     }
   },
   mounted() {

+ 119 - 0
src/views/BioSafety/chart/chartMin.vue

@@ -0,0 +1,119 @@
+<template>
+  <div :id="'chartMin-' + data.id" style="width: 750px; height: 190px"></div>
+</template>
+
+<script>
+export default {
+  name: "chartMin",
+  data() {
+    return {
+      myChart: null
+    }
+  },
+  props: {
+    data: {
+      type: Object,
+      default: function () {
+        return {
+          id: 0,
+          time: [],
+          data: [],
+          name: '默认',
+          unit: '%'
+        }
+      }
+    }
+  },
+  watch: {
+    data: {
+      handler(newVal) {
+        if(newVal) {
+          this.myChart.clear();
+          this.init()
+        }
+      },
+      deep: true
+    }
+  },
+  methods: {
+    init() {
+      // 获取当前数组的数量并push 成新数组
+      let option = {
+        grid: {
+          top: "5%",
+          left: "5%",
+          right: "5%",
+          bottom: "5%",
+          containLabel: true,
+        },
+        tooltip: {
+          trigger: 'axis',
+        },
+        color: ['#5470C6'],
+        xAxis: {
+          type: "category",
+          data: this.data.time,
+          axisLabel: {
+            color: "#fff",
+          },
+          nameTextStyle: {
+            color: "#fff",
+          },
+          axisLine: {
+            lineStyle: {
+              color: "#FFF",
+            },
+          },
+        },
+        yAxis: {
+          splitLine: { show: false },
+          axisLine: {
+            show: true,
+            lineStyle: {
+              type: "solid",
+              color: "#fff", //左边线的颜色
+              width: "2", //坐标线的宽度
+            },
+          },
+          axisLabel: {
+            formatter: `{value}${this.data.unit}`,
+            textStyle: {
+              color: "#fff",
+
+              fontSize: 12,
+            },
+          },
+          nameTextStyle: {
+            fontSize: 12,
+          },
+        },
+        series: [
+          {
+            data: this.data.data,
+            type: 'bar',
+            barWidth: 30,
+            label: {
+              show: true,
+              position: 'top',
+              color: '#fff'
+            },
+          }
+        ]
+      }
+      this.myChart.setOption(option)
+    }
+  },
+  mounted() {
+    this.myChart = this.$echarts.init(document.getElementById('chartMin-' + this.data.id));
+    this.init()
+    let that = this;
+    window.addEventListener('resize', function () {
+      that.myChart.resize()
+    })
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 47 - 4
src/views/Home/Home.vue

@@ -10,7 +10,7 @@
       <div class="content-center">
         <ul class="carousel" :style="{width: width + 'px', left: leftNum + 'px'}">
           <template v-for="(item, i) in list">
-            <li class="carousel-li" :key="item.id" @click="jump(item.url)" @mouseover="onChange(i)" @mouseout="initData">
+            <li class="carousel-li" :key="item.id" @click="jump(item)" @mouseover="onChange(i)" @mouseout="initData">
               <div class="box">
                 <div class="box-line box-top-right"></div>
                 <div class="box-line box-bottom-right"></div>
@@ -257,6 +257,16 @@
       <div class="home-footer-scatter"></div>
       <div :class="['home-footer-flash']"></div>
     </div>
+    <div class="bio-dialog" v-show="permissionShow" @click="permissionShow = false">
+      <div class="dialog-content1">
+        <div style="margin-bottom: 20px">
+          <i class="el-icon-error" style="font-size: 48px; color: red"></i>
+        </div>
+        <div style="color: white; font-size: 32px">
+          抱歉您暂无权限查看,请联系管理员
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
@@ -273,31 +283,37 @@ export default {
           id: 1,
           title: '生物安全',
           url: '/bioSafety',
+          permission: 'bioSafety:look'
         },
         {
           id: 2,
           title: '生态监测',
           url: '/zoology',
+          permission: 'zoology:look'
         },
         {
           id: 3,
           title: '生产经营',
           url: '/production',
+          permission: 'production:look'
         },
         {
           id: 4,
           title: '环境监测',
           url: '/environment',
+          permission: 'environment:look'
         },
         {
           id: 5,
           title: '报警信息',
           url: '/alarm',
+          permission: 'alarm:look'
         },
         {
           id: 6,
           title: '视频监控',
           url: '/monit',
+          permission: 'monit:look'
         },
       ],
       num: 0,
@@ -327,7 +343,8 @@ export default {
         tadaySiZhu: "0",
         tadayXiXiao: "0",
       },
-      alarm: {}
+      alarm: {},
+      permissionShow: false
     }
   },
   methods: {
@@ -416,8 +433,14 @@ export default {
         })
       }, 3000)
     },
-    jump(url) {
-      this.$router.push(url);
+    jump(item) {
+      // 是否有权限
+      if(this.hasPerm(item.permission)) {
+        this.$router.push(item.url);
+      } else {
+        this.permissionShow = true;
+      }
+
     },
   },
   mounted() {
@@ -734,4 +757,24 @@ export default {
       opacity: 1;
     }
   }
+  .bio-dialog {
+    width: 100vw;
+    height: 100vh;
+    position: absolute;
+    top: 0;
+    left: 0;
+    background-color: rgba(0,0,0, .9);
+    z-index: 999;
+  }
+  .dialog-content1 {
+    width: 25%;
+    position: absolute;
+    top: 40%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    border: 1px solid #007aff;
+    box-sizing: border-box;
+    padding: 40px;
+    /*background-color: #fff;*/
+  }
 </style>

+ 16 - 6
src/views/Login/Login.vue

@@ -43,7 +43,7 @@
 </template>
 
 <script>
-import { Login, getFarmId} from '../../utils/api';
+import { Login, getFarmId, getUserMenuScreen } from '../../utils/api';
 import { mapState, mapActions} from 'vuex'
 export default {
   name: "Login",
@@ -71,16 +71,26 @@ export default {
           localStorage.setItem('UserName', res.data.accountName);
           localStorage.setItem('UserId', res.data.id);
           this.$message.success('登录成功');
+          let userId = res.data.id
           getFarmId().then(res => {
             if(res.code === 10000) {
               this.setFarmIdAsync(res.data);
               localStorage.setItem('lastFarmId', res.data);
-              let url = this.$route.query.redirect;
-              if(url) {
-                this.$router.replace(url);
-              } else {
-                this.$router.replace('/');
+              let params = {
+                userId: userId
               }
+              getUserMenuScreen(params).then(res1=> {
+                if(res1.code === 10000) {
+                  let url = res1.data[0].url;
+                  this.$router.replace('/' + url);
+                }
+              })
+              // let url = this.$route.query.redirect;
+              // if(url) {
+              //   this.$router.replace(url);
+              // } else {
+              //   this.$router.replace('/');
+              // }
             }
           })
         } else {

+ 11 - 5
src/views/MainLayout.vue

@@ -48,7 +48,12 @@
       <p style="font-size: 12px; margin: 0; color: #fff; opacity: 0.4">本软件由杭州慧牧提供技术支持</p>
     </div>
     <div class="content">
-      <router-view></router-view>
+      <template v-if="hasPerm(routerSite + ':look')">
+        <router-view></router-view>
+      </template>
+      <template v-else>
+        <el-empty :image-size="200" description="暂无权限查看,请联系管理员"></el-empty>
+      </template>
     </div>
     <transition :name=" isHome ? 'moveL' : 'moveR' ">
       <div id="weather" :class="[isHome ? 'weather1' : 'weather2']" v-if="showWeather">
@@ -221,7 +226,8 @@ export default {
       alarmType: false,
       weatherList: [],
       alarmInfo: '',
-      timer: null
+      timer: null,
+      routerSite: '',
     }
   },
   watch: {
@@ -256,7 +262,7 @@ export default {
     ...mapState(['farmList', 'farmId'])
   },
   methods: {
-    ...mapActions(['GetFarm', 'setFarmIdAsync']),
+    ...mapActions(['GetFarm', 'setFarmIdAsync', 'GetButtons']),
     initTime() {
       var _this = this;
       this.timer4 = setInterval(function() {
@@ -370,14 +376,14 @@ export default {
   },
   created() {
     this.GetFarm()
+    this.GetButtons()
   },
   mounted() {
     this.init()
+    this.routerSite = this.$route.meta.permission;
     if (this.$route.name === 'Home') {
       this.isHome = true;
       this.initTime();
-      console.log(1111);
-      console.log(this.farmId)
     } else {
       this.isHome = false;
       this.title = this.$route.meta.title;

+ 253 - 55
src/views/Monit/Monit.vue

@@ -1,72 +1,107 @@
 <template>
   <div class="monit">
     <div class="monit-left">
-      <div class="monit-title" @click="isShow = !isShow">
-        <span style="font-size: 16px">选择监控:</span>
-        &emsp;
-        <el-cascader
-          v-model="videoId"
-          :options="options"
-          size="mini"
-          @change="handleChange"
-          :props="{value: 'id', label: 'cameraName', children: 'cameraList', expandTrigger: 'hover', disabled: 'runStatus'}"
-          :show-all-levels="false"></el-cascader>
+      <div class="btn" @click="show=true">视频列表</div>
+      <div class="btn btn-fixed" @click="showVideo = true">配置</div>
+<!--      <div class="monit-title" @click="isShow = !isShow">-->
+<!--        <span style="font-size: 16px">选择监控:</span>-->
+<!--        &emsp;-->
+<!--        <el-cascader-->
+<!--          v-model="videoId"-->
+<!--          :options="options"-->
+<!--          size="mini"-->
+<!--          @change="handleChange"-->
+<!--          :props="{value: 'id', label: 'cameraName', children: 'cameraList', expandTrigger: 'hover', disabled: 'runStatus'}"-->
+<!--          :show-all-levels="false"></el-cascader>-->
+<!--      </div>-->
+      <iframe v-if="isVideo" :src="'static/jinm/index.html?'+'1'+','+ cameraOne +','+ cameraTwo + ',' +'100%' + ',' + '0'" :style="{width: $store.state.screenVideo ? '100%': '80%', height: '100%', margin: '0 auto'}" frameborder="0"  allowfullscreen="true"></iframe>
+    </div>
+    <div class="monit-right" v-if="$store.state.screenVideo">
+      <swiper style="height: 100%;  margin-top: auto; margin-bottom: auto;" ref="mySwiper" class="swiper" :options="swiperOption">
+        <swiper-slide v-for="(item, i) in videoList" :key="i">
+          <div class="case">
+            <template v-if="num === 0 && (i === 0 || i === 1 || i === 2)">
+              <iframe  :src="'static/jinm/index.html?'+'1'+','+ item.wsUrl +','+ item.rtspUrl + ',' +'100%' + ',' + '0'" style="width: 100%; height: 100%;" frameborder="0"  allowfullscreen="true"></iframe>
+            </template>
+            <template v-else-if="num === 3 && (i ===3 || i === 4 || i === 5)">
+              <iframe  :src="'static/jinm/index.html?'+'1'+','+ item.wsUrl +','+ item.rtspUrl + ',' +'100%' + ',' + '0'" style="width: 100%; height: 100%;" frameborder="0"  allowfullscreen="true"></iframe>
+            </template>
+          </div>
+        </swiper-slide>
+      </swiper>
+    </div>
+    <div class="monit_left" v-show="show">
+      <div style="flex: 1; background-color: #fff">
+        <div class="boxTile" :class="[videoActive === i ? 'active' : '']" v-for="(item, i) in options" :key="i" @click="setVideo(item, i)">
+          {{item.cameraName}}
+        </div>
+      </div>
+      <div class="monit-scroll" style="flex: 1; overflow: auto; background-color: #fff">
+        <div class="boxTile" :class="[active === i ? 'active' : '']" v-for="(item, i) in videoItem" :key="i" @click="getVideoItems(item, i)">
+          {{item.cameraName}}
+        </div>
+      </div>
+      <div class="cancel" @click="show=false">关闭监控列表</div>
+    </div>
+    <div class="monit-dialog" v-show="showVideo" @click="showVideo = false">
+      <div class="monit-content1">
+        <div class="monit_box">
+          <h3>视 频 配 置</h3>
+          <div class="monit_flex">
+            <div class="monit_bise">
+              展 示 轮 巡
+            </div>
+            <div class="monit_bise" @click.stop>
+              <el-switch
+                active-color="#13ce66"
+                inactive-color="#ff4949"
+                v-model="$store.state.screenVideo"
+                @change="changeMode"></el-switch>
+            </div>
+          </div>
+        </div>
       </div>
-      <iframe v-if="isVideo" :src="'static/jinm/index.html?'+'1'+','+ cameraOne +','+ cameraTwo + ',' +'100%' + ',' + '0'" style="width: 80%; height: 100%; margin: 0 auto;" frameborder="0"  allowfullscreen="true"></iframe>
     </div>
-<!--    <div class="monit-right">-->
-<!--      <swiper style="height: 100%;  margin-top: auto; margin-bottom: auto;" ref="mySwiper" class="swiper" :options="swiperOption">-->
-<!--        <swiper-slide v-for="(item, i) in videoList" :key="i">-->
-<!--          <div class="case">-->
-<!--            <template v-if="num === 0 && (i === 0 || i === 1 || i === 2)">-->
-<!--              <iframe  :src="'static/jinm/index.html?'+'1'+','+ item.wsUrl +','+ item.rtspUrl + ',' +'100%' + ',' + '0'" style="width: 100%; height: 100%;" frameborder="0"  allowfullscreen="true"></iframe>-->
-<!--            </template>-->
-<!--            <template v-else-if="num === 3 && (i ===3 || i === 4 || i === 5)">-->
-<!--              <iframe  :src="'static/jinm/index.html?'+'1'+','+ item.wsUrl +','+ item.rtspUrl + ',' +'100%' + ',' + '0'" style="width: 100%; height: 100%;" frameborder="0"  allowfullscreen="true"></iframe>-->
-<!--            </template>-->
-<!--          </div>-->
-<!--        </swiper-slide>-->
-<!--      </swiper>-->
-<!--    </div>-->
   </div>
 </template>
 
 <script>
-// import { swiper, swiperSlide } from 'vue-awesome-swiper'
-// import 'swiper/css/swiper.css'
-import {getVideoAll, getVideo, saveVideo, lastVideo, romVideo} from "@/utils/api";
+import { swiper, swiperSlide } from 'vue-awesome-swiper'
+import 'swiper/css/swiper.css'
+import {getVideoAll, getVideo, saveVideo, lastVideo, romVideo, findOne, findUpdate} from "@/utils/api";
 import axios from "axios";
-// const c_swiper = document.getElementsByClassName("swiper")
+import { mapActions } from "vuex";
+const c_swiper = document.getElementsByClassName("swiper")
 
 export default {
   name: "Monit",
   components: {
-    // swiper,
-    // swiperSlide,
+    swiper,
+    swiperSlide,
   },
   data() {
     // let self = this;
     return {
-      // swiperOption: {
-      //   direction: 'vertical',
-      //   slidesPerView: 3,
-      //   slidesPerColumn: 1,
-      //   slidesPerGroup: 3,
-      //   // spaceBetween: 30,
-      //   autoplay: {
-      //     delay: 10000,
-      //     disableOnInteraction: false
-      //   },
-      //   on: {
-      //     slideChange() {
-      //       // console.log(c_swiper[0].swiper)
-      //       // this.num = c_swiper[0].swiper.activeIndex
-      //       self.returnNum(c_swiper[0].swiper.activeIndex)
-      //       // console.log(this.num);
-      //       // return this.num
-      //     }
-      //   }
-      // },
+      swiperOption: {
+        direction: 'vertical',
+        slidesPerView: 3,
+        slidesPerColumn: 1,
+        slidesPerGroup: 3,
+        // spaceBetween: 30,
+        autoplay: {
+          delay: 10000,
+          disableOnInteraction: false
+        },
+        on: {
+          slideChange() {
+            // console.log(c_swiper[0].swiper)
+            // this.num = c_swiper[0].swiper.activeIndex
+            self.returnNum(c_swiper[0].swiper.activeIndex)
+            // console.log(this.num);
+            // return this.num
+          }
+        }
+      },
       videoId: '',
       isShow: false,
       isVideo: false,
@@ -77,6 +112,11 @@ export default {
       timer: null,
       num: 0,
       index: true,
+      videoActive: 0,
+      videoItem: [],
+      active: '',
+      show: false,
+      showVideo: false,
     }
   },
   watch: {
@@ -102,6 +142,7 @@ export default {
     }
   },
   methods: {
+    ...mapActions(['setScreenVideoAsync']),
     init() {
       var that = this;
       axios.all([
@@ -115,6 +156,7 @@ export default {
             })
           })
           that.options = res1.data;
+          that.videoItem = that.options[0].cameraList;
         }
         if(res2.code === 10000) {
           that.isVideo = true;
@@ -146,15 +188,57 @@ export default {
     },
     returnNum(val) {
       this.num = val;
+    },
+    setVideo(item, i) {
+      this.videoItem = item.cameraList;
+      this.videoActive = i;
+    },
+    getVideoItems(item, i) {
+      this.active = i;
+      let params= {
+        cameraIds: [item.id],
+      }
+      getVideo(params).then(res =>{
+        this.isVideo = true;
+        this.cameraOne = res.data[0].wsUrl;
+        this.cameraTwo = res.data[0].rtspUrl;
+        saveVideo({cameraId: item.id}).then(res => {
+          console.log(res)
+        })
+      })
+    },
+    initConfig() {
+      findOne({  id: localStorage.getItem('UserId') }).then(res => {
+          if(res.code === 10000) {
+            if(res.data.screenVideo === 0) {
+              this.setScreenVideoAsync(false)
+            } else {
+              this.setScreenVideoAsync(true)
+            }
+          }
+      })
+    },
+    changeMode(val) {
+        let params = {
+          id: localStorage.getItem('UserId'),
+          screenVideo: val ? 1 : 0
+        }
+        findUpdate(params).then(res => {
+          console.log(res)
+        })
+        this.setScreenVideoAsync(val)
     }
   },
   mounted() {
     this.init()
     this.initCrmea();
-    // var that = this;
-    // this.timer = setInterval(() => {
-    //  that.initCrmea();
-    // }, 60000)
+    this.initConfig();
+    var that = this;
+    if(this.$store.state.screenVideo) {
+      this.timer = setInterval(() => {
+        that.initCrmea();
+      }, 60000)
+    }
   },
   beforeDestroy() {
     clearInterval(this.timer);
@@ -171,6 +255,7 @@ export default {
     padding: 20px 0 0 0;
     display: flex;
     justify-content: space-between;
+    position: relative;
   }
   .monit-left {
     flex: 1;
@@ -237,4 +322,117 @@ export default {
   .content-flex {
     flex: 1;
   }
+  .monit_left {
+    width: 400px;
+    height: 640px;
+    position: fixed;
+    top: 0;
+    left: 0;
+    background-color: rgba(0,0,0, .5);
+    box-sizing: border-box;
+    padding: 20px;
+    display: flex;
+  }
+  .boxTile {
+    width: 120px;
+    height: 30px;
+    line-height: 30px;
+    border: 1px solid #ddd;
+    text-align: center;
+    margin: 10px auto;
+    cursor: pointer;
+  }
+  .active {
+    background-color: #009cff;
+  }
+  .btn {
+    width: 60px;
+    height: 30px;
+    line-height: 30px;
+    background-color: #009cff;
+    text-align: center;
+    color: white;
+    position: absolute;
+    top: -15px;
+    cursor: pointer;
+  }
+  .btn-fixed {
+    top: -15px;
+    right: 25px;
+  }
+  .cancel {
+    width: 80px;
+    height: 30px;
+    line-height: 30px;
+    background-color: #009cff;
+    text-align: center;
+    color: white;
+    position: absolute;
+    right: -100px;
+    cursor: pointer;
+  }
+  .monit-scroll {
+    overflow: auto;
+  }
+  .monit-scroll::-webkit-scrollbar {
+    /*滚动条整体样式*/
+    width : 5px;  /*高宽分别对应横竖滚动条的尺寸*/
+    height: 1px;
+  }
+  .monit-scroll::-webkit-scrollbar-thumb {
+    /*滚动条里面小方块*/
+    border-radius   : 8px;
+    background-color:  #535353;
+    background-image: -webkit-linear-gradient(
+      45deg,
+      rgba(255, 255, 255, 0.2) 25%,
+      transparent 25%,
+      transparent 50%,
+      rgba(255, 255, 255, 0.2) 50%,
+      rgba(255, 255, 255, 0.2) 75%,
+      transparent 75%,
+      transparent
+    );
+  }
+  .monit-scroll::-webkit-scrollbar-track {
+    /*滚动条里面轨道*/
+    box-shadow   : inset 0 0 5px rgba(0, 0, 0, 0.2);
+    /*background   : #ededed;*/
+    border-radius: 10px;
+  }
+  .monit-dialog {
+    width: 100vw;
+    height: 100vh;
+    position: fixed;
+    top: 0;
+    left: 0;
+    background-color: rgba(0,0,0, .9);
+    z-index: 999;
+  }
+  .monit-content1 {
+    width: 50%;
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    /*background-color: #fff;*/
+  }
+  .monit_box {
+    height: 400px;
+    background-color: #007aff;
+    border-radius: 15px;
+    text-align: center;
+    box-sizing: border-box;
+    padding: 20px;
+    color: #fff;
+  }
+  .monit_flex {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+  .monit_bise {
+    width: 50%;
+    height: 50px;
+  }
 </style>

+ 52 - 53
src/views/Zoology/Zoology.vue

@@ -96,34 +96,37 @@
         </chart-board>
       </div>
       <div class="left-bottom">
-        <div class="flex-center">
-          <chart-board
-            :title="'整栋用电量'"
-            :ifDate="true"
-            @emitDates="getElecDates"
+
+          <div
+            class="right-bottom-left"
+            v-loading="chartLoading"
+            element-loading-text="拼命加载中"
+            element-loading-spinner="el-icon-loading"
+            element-loading-background="rgba(0, 0, 0, 0.8)"
           >
-            <template v-if="elecData.yAxisData.length > 0">
-              <chart-line-and :data="elecData" :id="2"></chart-line-and>
-            </template>
-            <template v-else>
-              <div style="font-size: 18px; line-height: 150px; color: white">暂无数据</div>
-            </template>
-          </chart-board>
-        </div>
-        <div class="flex-center">
-          <chart-board
-            :title="'整栋本周用料量'"
-            :ifDate="true"
-            @emitDates="getElecDates"
+            <chart-board :title="roomName + '温度'" @emitDates="getWaterDates">
+              <template v-if="tempData.yAxisData.length > 0">
+                <chart-line :data="tempData" :id="4"></chart-line>
+              </template>
+              <template v-else>
+                <div style="font-size: 18px; line-height: 150px; color: white">设备已掉线</div>
+              </template>
+            </chart-board>
+          </div>
+
+          <div
+            class="right-bottom-right"
+            v-loading="chartLoading"
+            element-loading-text="拼命加载中"
+            element-loading-spinner="el-icon-loading"
+            element-loading-background="rgba(0, 0, 0, 0.8)"
           >
-            <template v-if="fodderData.yAxisData.length > 0">
-              <chart-line :data="fodderData" :id="2"></chart-line>
-            </template>
-            <template v-else>
-              <div style="font-size: 18px; line-height: 150px; color: white">设备已掉线</div>
-            </template>
-          </chart-board>
-        </div>
+            <chart-board :title="roomName + '湿度'" @emitDates="getWaterDates">
+              <chart-line v-if="rhData.yAxisData.length > 0" :data="rhData" :id="5"></chart-line>
+              <div v-else style="font-size: 18px; line-height: 150px; color: white">设备已掉线</div>
+            </chart-board>
+          </div>
+
       </div>
     </div>
 
@@ -151,34 +154,30 @@
         </div>
       </div>
       <div class="right-bottom">
-        <div
-          class="right-bottom-left"
-          v-loading="chartLoading"
-          element-loading-text="拼命加载中"
-          element-loading-spinner="el-icon-loading"
-          element-loading-background="rgba(0, 0, 0, 0.8)"
+        <chart-board
+          :title="'整栋用电量'"
+          :ifDate="true"
+          @emitDates="getElecDates"
         >
-          <chart-board :title="roomName + '温度'" @emitDates="getWaterDates">
-            <template v-if="tempData.yAxisData.length > 0">
-              <chart-line :data="tempData" :id="4"></chart-line>
-            </template>
-            <template v-else>
-              <div style="font-size: 18px; line-height: 150px; color: white">设备已掉线</div>
-            </template>
-          </chart-board>
-        </div>
-        <div
-          class="right-bottom-right"
-          v-loading="chartLoading"
-          element-loading-text="拼命加载中"
-          element-loading-spinner="el-icon-loading"
-          element-loading-background="rgba(0, 0, 0, 0.8)"
+          <template v-if="elecData.yAxisData.length > 0">
+            <chart-line-and :data="elecData" :id="2"></chart-line-and>
+          </template>
+          <template v-else>
+            <div style="font-size: 18px; line-height: 150px; color: white">暂无数据</div>
+          </template>
+        </chart-board>
+        <chart-board
+          :title="'整栋本周用料量'"
+          :ifDate="true"
+          @emitDates="getElecDates"
         >
-          <chart-board :title="roomName + '湿度'" @emitDates="getWaterDates">
-            <chart-line v-if="rhData.yAxisData.length > 0" :data="rhData" :id="5"></chart-line>
-            <div v-else style="font-size: 18px; line-height: 150px; color: white">设备已掉线</div>
-          </chart-board>
-        </div>
+          <template v-if="fodderData.yAxisData.length > 0">
+            <chart-line :data="fodderData" :id="2"></chart-line>
+          </template>
+          <template v-else>
+            <div style="font-size: 18px; line-height: 150px; color: white">设备已掉线</div>
+          </template>
+        </chart-board>
       </div>
     </div>
   </div>
@@ -588,7 +587,7 @@ export default {
 }
 /* 左下 */
 .left-bottom {
-  background-color: rgb(228, 32, 32);
+  /*background-color: rgb(228, 32, 32);*/
   width: 100%;
   height: 26.3%;
   display: flex;