ソースを参照

Merge branch 'v0.1.1_test' of http://10.87.21.221:8000/jzyd_yyds/soc_web into v0.1.1_test

zhulu 1 年間 前
コミット
460baba0c0
34 ファイル変更2322 行追加294 行削除
  1. 84 0
      src/api/iot/board.js
  2. 19 0
      src/api/system/device.js
  3. 14 0
      src/router/index.js
  4. 2 1
      src/views/board/index.vue
  5. 105 0
      src/views/iot/board/components/alarmList.vue
  6. 157 0
      src/views/iot/board/components/alarmRate.vue
  7. 377 0
      src/views/iot/board/components/alarmTrend.vue
  8. 185 0
      src/views/iot/board/components/deviceCount.vue
  9. 258 0
      src/views/iot/board/components/deviceMap.vue
  10. 29 0
      src/views/iot/board/components/layout.vue
  11. 528 0
      src/views/iot/board/components/onlineAndHealth.vue
  12. 114 0
      src/views/iot/board/components/protection.vue
  13. 112 0
      src/views/iot/board/css/index.css
  14. BIN
      src/views/iot/board/img/consumption.png
  15. BIN
      src/views/iot/board/img/end.png
  16. BIN
      src/views/iot/board/img/environment.png
  17. BIN
      src/views/iot/board/img/fire.png
  18. BIN
      src/views/iot/board/img/g.png
  19. BIN
      src/views/iot/board/img/indent.png
  20. BIN
      src/views/iot/board/img/j.png
  21. BIN
      src/views/iot/board/img/left_line.png
  22. BIN
      src/views/iot/board/img/linx.png
  23. BIN
      src/views/iot/board/img/map.png
  24. BIN
      src/views/iot/board/img/monitor.png
  25. BIN
      src/views/iot/board/img/org.png
  26. BIN
      src/views/iot/board/img/right_line.png
  27. BIN
      src/views/iot/board/img/s.png
  28. BIN
      src/views/iot/board/img/sper.png
  29. BIN
      src/views/iot/board/img/t.png
  30. BIN
      src/views/iot/board/img/true.png
  31. BIN
      src/views/iot/board/img/vip.png
  32. 63 0
      src/views/iot/board/index.vue
  33. 7 6
      src/views/iot/server/index.vue
  34. 268 287
      src/views/system/device/index.vue

+ 84 - 0
src/api/iot/board.js

@@ -0,0 +1,84 @@
+import request from "@/utils/request";
+
+/**
+ * 设备数量
+ * @param {} orgId
+ */
+export function deviceCount(orgId) {
+  return request({
+    url: "/iot/board/deviceCount/" + orgId,
+    method: "get",
+  });
+}
+
+/**
+ * 防区信息
+ * @param {*} orgId
+ * @returns
+ */
+export function protectionInfo(orgId) {
+  return request({
+    url: "/iot/board/protection/" + orgId,
+    method: "get",
+  });
+}
+
+/**
+ * 设备在线率
+ * @param {*} orgId
+ * @returns
+ */
+export function deviceOnline(orgId) {
+  return request({
+    url: "/iot/board/deviceOnline/" + orgId,
+    method: "get",
+  });
+}
+
+/**
+ * 设备健康状态
+ * @param {*} orgId
+ * @returns
+ */
+export function deviceHealth(orgId) {
+  return request({
+    url: "/iot/board/deviceHealth/" + orgId,
+    method: "get",
+  });
+}
+
+/**
+ * 设备告警趋势
+ * @param {*} orgId
+ * @returns
+ */
+export function alarmTrend(orgId) {
+  return request({
+    url: "/iot/board/alarmTrend/" + orgId,
+    method: "get",
+  });
+}
+
+/**
+ * 设备实时告警率
+ * @param {*} orgId
+ * @returns
+ */
+export function alarmRate(orgId) {
+  return request({
+    url: "/iot/board/alarmRate/" + orgId,
+    method: "get",
+  });
+}
+
+/**
+ * 设备告警列表
+ * @param {*} orgId
+ * @returns
+ */
+export function alarmList(orgId) {
+  return request({
+    url: "/iot/board/alarmList/" + orgId,
+    method: "get",
+  });
+}

+ 19 - 0
src/api/system/device.js

@@ -64,3 +64,22 @@ export function delDevice(id) {
     method: 'delete'
   })
 }
+
+// 查询资产字典
+export function getDictTree() {
+  return request({
+    url: '/system/dictionary/list',
+    method: 'get'
+  })
+}
+
+// 查询资产字典
+export function getDictTreeByParentId(parentId) {
+  return request({
+    url: '/system/dictionary/getDictTreeByParentId',
+    method: 'get',
+    params: {parentId: parentId}
+  })
+}
+
+

+ 14 - 0
src/router/index.js

@@ -135,6 +135,20 @@ export const constantRoutes = [
       },
     ],
   },
+  {
+    path: "/iot",
+    component: Layout,
+    hidden: true,
+    redirect: "noredirect",
+    children: [
+      {
+        path: "board",
+        component: () => import("@/views/iot/board/index"),
+        name: "iot_board",
+        meta: { title: "物联看板", icon: "user" },
+      },
+    ],
+  },
 ];
 
 // 动态路由,基于用户权限动态去加载

+ 2 - 1
src/views/board/index.vue

@@ -367,7 +367,8 @@ export default {
     color: #8e949c;
     padding: 0 5px;
     font-size: 12px;
-
+    background-color:transparent;
+    display: inline-block;
     &:hover {
       color: #ffffff;
     }

+ 105 - 0
src/views/iot/board/components/alarmList.vue

@@ -0,0 +1,105 @@
+<template>
+    <div class="component_box" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
+        <h1 class="t_title">实时告警列表</h1>
+        <el-table :data="data" width="100%">
+            <el-table-column label="所在机构" prop="orgName" align="center"></el-table-column>
+            <el-table-column label="告警设备" prop="deviceName" align="center"></el-table-column>
+            <el-table-column label="告警时间" prop="alarmTime" align="center"></el-table-column>
+            <el-table-column label="告警信息" prop="alarmInfo" align="center"></el-table-column>
+        </el-table>       
+    </div>
+</template>
+<script>
+import { alarmList } from "@/api/iot/board";
+export default {
+    props: {
+        orgId: {
+            type: String,
+            isRequired: true,
+        },
+    },
+    data() {
+        return {
+            data: [],
+        };
+    },
+
+    components: {},
+
+    computed: {},
+
+    watch: {
+        orgId: {
+            deep: true,
+            handler(val) {
+                this.resetTimer();
+                this.getData();
+            },
+        },
+    },
+    created() {
+        this.refreshTime = 1 * 10 * 1000;
+        this.isMouseOver = false;
+    },
+    mounted() {
+
+    },
+    methods: {
+        async getData() {
+            let r = (await alarmList(this.orgId))
+                .data;
+            this.data = r;
+        },
+        resetTimer() {
+            this.timer && clearInterval(this.timer);
+            this.timer = setInterval(() => {
+                if (this.isMouseOver) {
+                    return;
+                }
+
+                this.getData();
+            }, this.refreshTime);
+        },
+    }
+}
+</script>
+<style scoped src="./../css/index.css"></style>
+<style lang="scss" scoped>
+.t_table {
+    font-size: 14px;
+    color: #fff;
+    width: 94%;
+    margin: 0 auto;
+    border-spacing: 0;
+    text-align: center;
+    box-sizing: border-box;
+    margin-top: 10%;
+}
+
+.t_table tr {
+    margin: 0;
+    padding: 0;
+    height: 40px;
+}
+
+.t_table thead tr {
+    background: #053a98;
+}
+
+.t_table tbody tr td:first-child {
+    border-left: 1px solid #053a98;
+}
+
+.t_table td {
+    border-bottom: 1px solid #053a98;
+    border-right: 1px solid #053a98;
+}
+
+.t_title {
+    position: absolute;
+    font-size: 20px;
+    color: #fff;
+    left: 5%;
+    top: 10%;
+}
+</style>

+ 157 - 0
src/views/iot/board/components/alarmRate.vue

@@ -0,0 +1,157 @@
+<template>
+    <div class="component_box">
+        <div ref="chart" style="width: 100%; height: 100%;" @mouseenter="handleMouseEnter"
+            @mouseleave="handleMouseLeave"></div>
+    </div>
+</template>
+<script>
+import { alarmRate } from '@/api/iot/board'
+export default {
+    props: {
+        orgId: {
+            type: String,
+            isRequired: true,
+        },
+    },
+    data() {
+        return {
+            data: {
+                normalCount: 0,
+                alarmCount: 0
+            },
+            // activeName: types[0].value,
+        };
+    },
+
+    components: {},
+
+    computed: {},
+
+    watch: {
+        orgId: {
+            deep: true,
+            handler(val) {
+                this.resetTimer();
+                this.getData();
+            },
+        },
+        data: {
+            deep: true,
+            handler() {
+                this.initMap();
+            },
+        },
+    },
+
+    created() {
+        this.refreshTime = 1 * 10 * 1000;
+        this.isMouseOver = false;
+    },
+
+    async mounted() {
+        window.addEventListener("resize", this.windowResize);
+    },
+    beforeDestroy() {
+        this.timer && clearInterval(this.timer);
+        this.timer = null;
+
+        window.removeEventListener("resize", this.windowResize);
+    },
+
+    methods: {
+        handleClick() {
+            this.resetTimer();
+            this.getData();
+        },
+        handleMouseEnter() {
+            this.isMouseOver = true;
+        },
+        handleMouseLeave() {
+            this.isMouseOver = false;
+        },
+        async getData() {
+            let r = (await alarmRate(this.orgId))
+                .data;
+            this.data = r;
+        },
+
+        windowResize() {
+            this.myChart && this.myChart.resize();
+        },
+        initMap() {
+            this.myChart && this.myChart.dispose();
+            let c = this.$refs["chart"];
+
+            // 基于准备好的dom,初始化echarts实例
+            this.myChart = echarts.init(
+                c
+            );
+            option = {
+                title: {
+                    text: "设备告警状态",
+                    top: 35,
+                    left: 20,
+                    textStyle: {
+                        fontSize: 18,
+                        color: "#fff",
+                    },
+                },
+                tooltip: {
+                    trigger: "item",
+                    formatter: "{a} <br/>{b}: {c} ({d}%)",
+                },
+                legend: {
+                    right: 20,
+                    top: 35,
+                    data: ["告警", "正常"],
+                    textStyle: {
+                        color: "#fff",
+                    },
+                },
+                series: [
+                    {
+                        name: "设备告警状态",
+                        type: "pie",
+                        radius: ["0", "60%"],
+                        center: ["50%", "60%"],
+                        // color: ['#e72325', '#98e002', '#2ca3fd'],
+                        color: ["#F6A645", "#13D0B2", "#2ca3fd"],
+                        label: {
+                            normal: {
+                                formatter: "{b}\n{d}%",
+                            },
+                        },
+                        data: [
+                            {
+                                value: this.data.alarmCount,
+                                name: "告警",
+                            },
+                            {
+                                value: this.data.normalCount,
+                                name: "正常",
+                                selected: true,
+                            },
+                        ],
+                    },
+                ],
+            };
+            // 使用刚指定的配置项和数据显示图表。
+            if (option && typeof option === "object") {
+                this.myChart.setOption(option);
+            }
+        },
+
+        resetTimer() {
+            this.timer && clearInterval(this.timer);
+            this.timer = setInterval(() => {
+                if (this.isMouseOver) {
+                    return;
+                }
+                // this.activeName = getNextPeriod(this.types, this.activeName);
+                this.getData();
+            }, this.refreshTime);
+        },
+    },
+};
+</script>
+<style scoped src="./../css/index.css"></style>

+ 377 - 0
src/views/iot/board/components/alarmTrend.vue

@@ -0,0 +1,377 @@
+<template>
+    <div class="component_box">
+        <div ref="chart" style="width: 100%; height: 100%;" @mouseenter="handleMouseEnter"
+            @mouseleave="handleMouseLeave"></div>
+    </div>
+</template>
+<script>
+import { alarmTrend } from '@/api/iot/board'
+export default {
+    props: {
+        orgId: {
+            type: String,
+            isRequired: true,
+        },
+    },
+    data() {
+        return {
+            data: {
+                date: [], //x轴的日期
+                total: [], //报警总数
+                countByType: [],//按分类统计的报警总数
+            },
+            isMouseOver: false,
+            // activeName: types[0].value,
+        };
+    },
+
+    components: {},
+
+    computed: {},
+
+    watch: {
+        orgId: {
+            deep: true,
+            handler(val) {
+                this.resetTimer();
+                this.getData();
+            },
+        },
+        data: {
+            deep: true,
+            handler() {
+                this.initMap();
+            },
+        },
+    },
+
+    created() {
+        this.types = types;
+        this.maxDisplay = 16;
+        this.refreshTime = 1 * 10 * 1000;
+        this.isMouseOver = false;
+    },
+
+    async mounted() {
+        window.addEventListener("resize", this.windowResize);
+    },
+    beforeDestroy() {
+        this.timer && clearInterval(this.timer);
+        this.timer = null;
+
+        window.removeEventListener("resize", this.windowResize);
+    },
+
+    methods: {
+        // handleClick() {
+        //     this.resetTimer();
+        //     this.getData();
+        // },
+        handleMouseEnter() {
+            this.isMouseOver = true;
+        },
+        handleMouseLeave() {
+            this.isMouseOver = false;
+        },
+        async getData() {
+            let r = (await alarmTrend(this.orgId))
+                .data;
+            let data = {
+                date: [], //x轴的日期
+                total: [], //报警总数
+                countByType: [],//按分类统计的报警总数
+            };
+
+            let monitorCount = [];
+            let fireCount = [];
+            let environmentCount = [];
+            for (let item of r) {
+                data.total.push(item.total);
+                monitorCount.push(item.monitorCount);
+                fireCount.push(item.fireCount);
+                environmentCount.push(item.environmentCount);
+
+                data.date.push(item.orgName);
+            }
+
+            data.countByType.push(monitorCount)
+            data.countByType.push(fireCount)
+            data.countByType.push(environmentCount);
+            this.data = data;
+        },
+
+        windowResize() {
+            this.myChart && this.myChart.resize();
+        },
+        initMap() {
+            this.myChart && this.myChart.dispose();
+            let c = this.$refs["chart"];
+
+            // 基于准备好的dom,初始化echarts实例
+            this.myChart = echarts.init(
+                c
+            );
+            var data = {
+                id: "multipleBarsLines",
+                title: "近7天告警趋势",
+                legendBar: ["报警总数"],
+                symbol: "", //数值是否带百分号        --默认为空 ''
+                legendLine: ["监控设备", "消防设备", "环境监测"],
+                // xAxis: ["9月19", "9月20", "9月21", "9月22", "9月23", "9月24", "9月25"],
+                // yAxis: [[8, 10, 10, 11, 4, 13, 8]],
+                // lines: [
+                //     [4, 3, 2, 4, 2, 1, 1],
+                //     [2, 1, 4, 2, 3, 2, 4],
+                //     [1, 0, 2, 1, 1, 2, 1],
+                // ],
+                barColor: ["#3FA7DC", "#7091C4", "#5170A2"], //柱子颜色 必填参数
+                lineColor: ["#D9523F"], // 折线颜色
+            };
+            /////////////end/////////
+
+            var myData = (function test() {
+                var yAxis = this.data.total || [];
+                var lines = this.data.countByType || [];
+                var legendBar = data.legendBar || [];
+                var legendLine = data.legendLine || [];
+                var symbol = data.symbol || " ";
+                var seriesArr = [];
+                var legendArr = [];
+                yAxis &&
+                    yAxis.forEach((item, index) => {
+                        legendArr.push({
+                            name: legendBar && legendBar.length > 0 && legendBar[index],
+                        });
+                        seriesArr.push({
+                            name: legendBar && legendBar.length > 0 && legendBar[index],
+                            type: "bar",
+                            barGap: "0.5px",
+                            data: item,
+                            barWidth: data.barWidth || 12,
+                            label: {
+                                normal: {
+                                    show: true,
+                                    formatter: "{c}" + symbol,
+                                    position: "top",
+                                    textStyle: {
+                                        color: "#fff",
+                                        fontStyle: "normal",
+                                        fontFamily: "微软雅黑",
+                                        textAlign: "left",
+                                        fontSize: 11,
+                                    },
+                                },
+                            },
+                            itemStyle: {
+                                //图形样式
+                                normal: {
+                                    barBorderRadius: 4,
+                                    color: data.barColor[index],
+                                },
+                            },
+                        });
+                    });
+
+                lines &&
+                    lines.forEach((item, index) => {
+                        legendArr.push({
+                            name: legendLine && legendLine.length > 0 && legendLine[index],
+                        });
+                        seriesArr.push({
+                            name: legendLine && legendLine.length > 0 && legendLine[index],
+                            type: "line",
+                            data: item,
+                            itemStyle: {
+                                normal: {
+                                    color: data.lineColor[index],
+                                    lineStyle: {
+                                        width: 3,
+                                        type: "solid",
+                                    },
+                                },
+                            },
+                            label: {
+                                normal: {
+                                    show: false, //折线上方label控制显示隐藏
+                                    position: "top",
+                                },
+                            },
+                            symbol: "circle",
+                            symbolSize: 10,
+                        });
+                    });
+
+                return {
+                    seriesArr,
+                    legendArr,
+                };
+            })();
+
+            option = {
+                title: {
+                    show: true,
+                    top: "10%",
+                    left: "3%",
+                    text: data.title,
+                    textStyle: {
+                        fontSize: 18,
+                        color: "#fff",
+                    },
+                    subtext: data.subTitle,
+                    link: "",
+                },
+                tooltip: {
+                    trigger: "axis",
+                    formatter: function (params) {
+                        var time = "";
+                        var str = "";
+                        for (var i of params) {
+                            time = i.name.replace(/\n/g, "") + "<br/>";
+                            if (i.data == "null" || i.data == null) {
+                                str += i.seriesName + ":无数据" + "<br/>";
+                            } else {
+                                str += i.seriesName + ":" + i.data + symbol + "%<br/>";
+                            }
+                        }
+                        return time + str;
+                    },
+                    axisPointer: {
+                        type: "none",
+                    },
+                },
+                legend: {
+                    right: data.legendRight || "30%",
+                    top: "12%",
+                    right: "5%",
+                    itemGap: 16,
+                    itemWidth: 10,
+                    itemHeight: 10,
+                    data: myData.legendArr,
+                    textStyle: {
+                        color: "#fff",
+                        fontStyle: "normal",
+                        fontFamily: "微软雅黑",
+                        fontSize: 12,
+                    },
+                },
+                grid: {
+                    x: 30,
+                    y: 80,
+                    x2: 30,
+                    y2: 60,
+                },
+                xAxis: {
+                    type: "category",
+                    data: this.data.date,
+                    axisTick: {
+                        show: false,
+                    },
+
+                    axisLine: {
+                        show: true,
+                        lineStyle: {
+                            color: "#1AA1FD",
+                        },
+                        symbol: ["none", "arrow"],
+                    },
+                    axisLabel: {
+                        show: true,
+                        interval: "0",
+                        textStyle: {
+                            lineHeight: 16,
+                            padding: [2, 2, 0, 2],
+                            height: 50,
+                            fontSize: 12,
+                        },
+                        rich: {
+                            Sunny: {
+                                height: 50,
+                                // width: 60,
+                                padding: [0, 5, 0, 5],
+                                align: "center",
+                            },
+                        },
+                        formatter: function (params, index) {
+                            var newParamsName = "";
+                            var splitNumber = 5;
+                            var paramsNameNumber = params && params.length;
+                            if (paramsNameNumber && paramsNameNumber <= 4) {
+                                splitNumber = 4;
+                            } else if (paramsNameNumber >= 5 && paramsNameNumber <= 7) {
+                                splitNumber = 4;
+                            } else if (paramsNameNumber >= 8 && paramsNameNumber <= 9) {
+                                splitNumber = 5;
+                            } else if (paramsNameNumber >= 10 && paramsNameNumber <= 14) {
+                                splitNumber = 5;
+                            } else {
+                                params = params && params.slice(0, 15);
+                            }
+
+                            var provideNumber = splitNumber; //一行显示几个字
+                            var rowNumber = Math.ceil(paramsNameNumber / provideNumber) || 0;
+                            if (paramsNameNumber > provideNumber) {
+                                for (var p = 0; p < rowNumber; p++) {
+                                    var tempStr = "";
+                                    var start = p * provideNumber;
+                                    var end = start + provideNumber;
+                                    if (p == rowNumber - 1) {
+                                        tempStr = params.substring(start, paramsNameNumber);
+                                    } else {
+                                        tempStr = params.substring(start, end) + "\n";
+                                    }
+                                    newParamsName += tempStr;
+                                }
+                            } else {
+                                newParamsName = params;
+                            }
+                            params = newParamsName;
+                            return "{Sunny|" + params + "}";
+                        },
+                        color: "#1AA1FD",
+                    },
+                },
+                yAxis: {
+                    axisLine: {
+                        show: true,
+                        lineStyle: {
+                            color: "#1AA1FD",
+                        },
+                        symbol: ["none", "arrow"],
+                    },
+                    type: "value",
+                    axisTick: {
+                        show: false,
+                    },
+                    axisLabel: {
+                        show: false,
+                    },
+                    splitLine: {
+                        show: false,
+                        lineStyle: {
+                            color: "#1AA1FD",
+                            type: "solid",
+                        },
+                    },
+                },
+                series: myData.seriesArr,
+            };
+            // 使用刚指定的配置项和数据显示图表。
+            if (option && typeof option === "object") {
+                this.myChart.setOption(option);
+            }
+        },
+
+        resetTimer() {
+            this.timer && clearInterval(this.timer);
+            this.timer = setInterval(() => {
+                if (this.isMouseOver) {
+                    return;
+                }
+                this.activeName = getNextPeriod(this.types, this.activeName);
+                this.getData();
+            }, this.refreshTime);
+        },
+    },
+};
+</script>
+<style scoped src="./../css/index.css"></style>

+ 185 - 0
src/views/iot/board/components/deviceCount.vue

@@ -0,0 +1,185 @@
+<template>
+    <div class="component_box">
+        <div class="t_mbox t_rbox">
+            <div>
+                <i></i>
+            </div>
+            <div>
+                <div>
+                    <span>视频监控设备</span>
+                    <span>{{ info.monitorCount }}</span>
+                </div>
+            </div>
+        </div>
+        <div class="t_mbox t_gbox">
+            <div>
+                <i></i>
+            </div>
+            <div>
+                <div>
+                    <span>消防预警设备</span>
+                    <span>{{ info.fireCount }}</span>
+                </div>
+            </div>
+        </div>
+        <div class="t_mbox t_ybox">
+            <div>
+                <i></i>
+            </div>
+            <div>
+                <div>
+                    <span>环境监测设备</span>
+                    <span>{{ info.environmentCount }}</span>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+import { deviceCount } from "@/api/iot/board";
+export default {
+    data() {
+        return {
+            info: {
+                monitorCount: 0,
+                fireCount: 0,
+                environmentCount: 0
+            },
+        }
+    },
+    props: {
+        orgId: {
+            type: String,
+            isRequired: true,
+        }
+    },
+    watch: {
+        orgId: {
+            deep: true,
+            handler(val) {
+                this.resetTimer();
+                this.getData();
+            },
+        }
+    },
+    created() {
+        this.refreshTime = 1 * 10 * 1000;
+        this.isMouseOver = false;
+    },
+    methods: {
+        getData() {
+            deviceCount(this.orgId).then(r => {
+                this.info = r.data;
+            })
+        },
+        beforeDestroy() {
+            this.timer && clearInterval(this.timer);
+            this.timer = null;
+        },
+        resetTimer() {
+            this.timer && clearInterval(this.timer);
+            this.timer = setInterval(() => {
+                // if (this.isMouseOver) {
+                //     return;
+                // }
+                // this.activeName = getNextPeriod(this.types, this.activeName);
+                this.getData();
+            }, this.refreshTime);
+        },
+    }
+}
+</script>
+<style scoped src="./../css/index.css"></style>
+<style lang="scss" scoped>
+.t_mbox {
+    width: 90%;
+    height: 28.33%;
+    /* position: relative; */
+    margin: 0 auto;
+    margin-top: 5%;
+    display: flex;
+}
+
+.t_mbox>div {
+    height: 100%;
+    display: flex;
+    align-items: center;
+}
+
+.t_mbox>div:first-child {
+    width: 40%;
+    text-align: right;
+    padding-left: calc(40% - 50px - 10px);
+}
+
+.t_mbox>div:first-child>i {
+    display: block;
+    width: 50px;
+    height: 50px;
+    /* top: 0;
+    bottom: 0; */
+}
+
+.t_mbox>div:nth-child(2) {
+    width: 60%;
+    display: flex;
+    justify-content: center;
+}
+
+
+// .t_mbox>div:nth-child(2) h2 {
+//     font-size: 20px;
+//     color: #fff;
+//     // position: relative;
+//     // top: 50%;
+//     // left: 50%;
+// }
+.t_mbox>div:nth-child(2)>div {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+}
+
+.t_mbox>div:nth-child(2)>div span {
+    font-size: 20px;
+    color: #fff;
+
+    // position: relative;
+    // top: 24%;
+    // left: 48%;
+}
+
+.t_mbox>div:nth-child(2)>div span:last-child {
+    margin-top: 10px;
+}
+
+.t_rbox {
+    background: #d9523f;
+    /* #44AFF0 */
+}
+
+.t_gbox {
+    background: #13d0b2;
+}
+
+.t_ybox {
+    background: #f6a645;
+    /* #4777F5 */
+}
+
+
+.t_rbox i {
+    background: url(../img/monitor.png) no-repeat;
+    background-size: 100% 100%;
+}
+
+.t_gbox i {
+    background: url(../img/fire.png) no-repeat;
+    background-size: 100% 100%;
+}
+
+.t_ybox i {
+    background: url(../img/environment.png) no-repeat;
+    background-size: 100% 100%;
+}
+</style>

+ 258 - 0
src/views/iot/board/components/deviceMap.vue

@@ -0,0 +1,258 @@
+
+
+
+<!--  -->
+<template>
+    <div class="component_box">
+      <div id="iot_map_Chart" style="height: 100%"></div>
+    </div>
+  </template>
+  
+  <script>
+
+  import * as echarts from "echarts";
+  import { getMap,mapInfo } from "@/api/board/cockpit.js";
+  
+  export default {
+    props: ["orgId", "orgName"],
+    data() {
+      return {
+        map: {},
+        coordinates: [],
+        icon: "image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAAUCAYAAABvVQZ0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAF3SURBVDhPvZTBK4RBGIe/z56UklDay+6JkhM3RYo/wVlOrg4uTtyc3JSrg6Lc2CQHp5U7RyVylBBJXD7PO/PO7M43Y3OQp57mfd/fzOz6dlf2LxRFMYLr2hro63io7e/gQI53uKwjA303Cr06CujStcwV1rCHg3Kpgf4E1/CBtsraGTbN4wv24Q0K2/hsy2IFN/FJj6Rhw4zshg2ctGVxodkcfmET+/EVd8zBFISXKH+O1HtSQ92EQD2Bo1rfSggLJmyHoQvNZYK27nKXm3fDGu030I/ZsecDh/DIdCHy9Ti1peceK+6yFGeaLaE8q1UcxllMYR8HxYHtI4IHTO8+oDJvOOA2VfFTpgm2zCagfrejiIZuaaFBhGb+gZfYNYfLEKQeuFDBny7zX50IwvIn1emdTZlDSuq3ua+r41rX8jzL87ypZQyvVLMvGDCoseTuV+EI/kUFEB7bPZ5FjTw6b2dcoxYMGzbznGsUwHzaxp5Hjf6SLPsG2jnZyz2k38wAAAAASUVORK5CYII=",
+      };
+    },
+  
+    components: {},
+  
+    computed: {},
+  
+    watch: {
+      orgId: {
+        deep: true,
+        handler(val) {
+          //   this.resetTimer();
+          this.getData();
+        },
+      },
+      // map: {
+      //   deep: true,
+      //   handler() {
+      //     this.$nextTick(() => {
+      //       this.initMap();
+      //     });
+      //   },
+      // },
+    },
+  
+    created() {
+      //   this.types = types;
+      //   this.maxDisplay = 16;
+      //   this.refreshTime = 1 * 10 * 1000;
+      this.isMouseOver = false;
+    },
+  
+    async mounted() {
+      // console.info(this.fjMap)
+  
+      window.addEventListener("resize", this.windowResize);
+    },
+    beforeDestroy() {
+      this.timer && clearInterval(this.timer);
+      this.timer = null;
+  
+      window.removeEventListener("resize", this.windowResize);
+    },
+  
+    methods: {
+      // handleClick() {
+      //   this.resetTimer();
+      //   this.getData();
+      // },
+      handleMouseEnter() {
+        this.isMouseOver = true;
+      },
+      handleMouseLeave() {
+        this.isMouseOver = false;
+      },
+      async getData() {
+        let mapinfo= await mapInfo(this.orgId);
+  
+        let map = mapinfo.data.map;
+        let coordinates =mapinfo.data.sites.map(s=>({ name: s.orgName, value: [s.longitude,s.latitude, 10] })); 
+        this.map = map;
+        this.coordinates = coordinates;
+        this.$nextTick(() => {
+          this.initMap();
+        });
+      },
+      initMap() {
+        this.myChart && this.myChart.dispose();
+  
+        // 基于准备好的dom,初始化echarts实例
+        this.myChart = echarts.init(document.getElementById("iot_map_Chart"));
+        let t = this;
+  
+        getMap(this.map).then((data) => {
+          echarts.registerMap("map", data);
+  
+          let option = {
+            tooltip: {
+              trigger: "item",
+            },
+            geo: {
+              show: true,
+              map: "map",
+              zoom: 1.25,
+  
+              showLegendSymbol: false, // 存在legend时显示
+  
+              label: {
+                normal: {
+                  show: false,
+                  color: "#c1b496", //控制地图省市文字颜色
+                  fontSize: 14,
+                },
+                emphasis: {
+                  show: false,
+                  color: "#fff", //悬浮字体颜色
+                },
+              },
+  
+              roam: true,
+              selectedMode: "single", //选择模式,单选,只能选中一个地市
+              select: {
+                //这个就是鼠标点击后,地图想要展示的配置
+                disabled: false, //可以被选中
+                itemStyle: {
+                  //相关配置项很多,可以参考echarts官网
+                  borderWidth: 1, //区域边框宽度
+                  borderColor: "#2B91B7ff", //区域边框颜色
+                  areaColor: "#2B91B730", //选中
+                },
+                label: {
+                  show: false,
+                  color: "#fff", //悬浮字体颜色
+                },
+              },
+              itemStyle: {
+                normal: {
+                  borderWidth: 1, //区域边框宽度
+                  borderColor: "#3fdaffff", //区域边框颜色
+                  areaColor: "#3fdaff55", //区域颜色"rgba(23,107,221,0.7)",//
+                },
+                emphasis: {
+                  borderWidth: 1,
+                  borderColor: "#fff",
+                  areaColor: "#2B91B7",
+                },
+              },
+            },
+            legend: [
+              {
+                selectedMode: true, //取消图例上的点击事件
+              },
+            ],
+            series: [
+              {
+                map: "map",
+                type: "effectScatter",
+                // silent: true,
+                coordinateSystem: "geo",
+                // datasetIndex: 0,
+                // geoIndex: 0,
+                // selectedMode: false,
+                // focusNodeAdjacency: false,
+                // label: {
+                // 	show: true,
+                // 	width: 13,
+                // 	height: 15,
+                // 	fontSize: 0,
+                // 	color: "#1DF9FC",
+                // 	backgroundColor: {
+                // 		image: iconRQ
+                // 	},
+                // },
+                label: {
+                  formatter: (param) => {
+                    return param.name;
+                  },
+                  position: "top",
+                  fontSize: "10",
+                  color: "#fff",
+                  show: true,
+                },
+                tooltip: {
+                  show: false,
+                },
+                //  tooltip:{
+                //   position: "right",
+                //   textStyle:{
+                //     // color:'#fff',
+                //   },
+                //   // backgroundColor:'rgba(184,189,192,1)',
+                //   formatter:function(param){
+                //     return `<div >
+                //     <div> ${param.data.name} </div>
+                //     <div>履职总数:85 </div>
+                //     <div> 已完成:67 </div>
+                //     </div>`
+                //   }
+                // },
+                itemStyle: {
+                  color: "#ddb926",
+                },
+                symbol: this.icon, //自定义图标
+                symbolSize: [10, 10],
+                // encode: {
+                //   value: 2,
+                // },
+                // showEffectOn: "emphasis", //关闭涟漪
+                // hoverEffectOn: true,
+                rippleEffect: {
+                  brushType: "fill",
+                  period: 0,
+                  number: 0,
+                },
+                data: this.coordinates,
+              },
+            ],
+          };
+          if (option && typeof option === "object") {
+            this.myChart.setOption(option);
+          }
+        });
+      },
+      windowResize() {
+        this.myChart && this.myChart.resize();
+      },
+    },
+  };
+  </script>
+  <style scoped src="./../css/index.css"></style>
+  <style lang="scss" scoped>
+  .content {
+    display: flex;
+  
+    margin-bottom: 20px;
+    margin-left: 5px;
+    margin-right: 5px;
+    border: solid 1px #b8bdc088;
+  
+    & > span {
+      margin-right: 10px;
+      padding-top: 5px;
+      padding-bottom: 5px;
+      height: 30px;
+      color: rgb(245, 245, 245);
+      font-size: 14px;
+    }
+  
+    & > span:first-child {
+      width: 100px;
+      background-color: #b8bdc088;
+      text-align: center;
+    }
+  }
+  </style>
+  

+ 29 - 0
src/views/iot/board/components/layout.vue

@@ -0,0 +1,29 @@
+<template>
+    <div :class="className+ ' iot_board_layout'">
+        <img class="t_l_line" src="../img/left_line.png" alt="">
+        <slot></slot>
+        <img class="t_r_line" src="../img/right_line.png" alt="">
+    </div>
+</template>
+<script>
+    export default {
+        name: 'iot_board_layout',
+        props:["className"]
+    }
+</script>
+<style scoped>
+.iot_board_layout{
+    padding:18px;
+    position:relative;
+}
+.t_l_line {
+    position: absolute;
+    top: 18px;
+    left: 18px;
+}
+.t_r_line {
+    position: absolute;
+    bottom: 18px;
+    right: 18px;
+}
+</style>

+ 528 - 0
src/views/iot/board/components/onlineAndHealth.vue

@@ -0,0 +1,528 @@
+<template>
+    <div class="component_box" style="display: flex;" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
+        <div ref="chart" style="width: 50%; height: 100%; "></div>
+        <div class="health">
+            <header class="header">
+                <span>网点设备健康度检查</span>
+                <!-- <h3><span>网点数:100</span></h3> -->
+                <!-- <img src="img/end.png"></img> -->
+                <!-- <span>已检查:90</span> -->
+            </header>
+            <main class="banklet_main">
+                <!-- <img src="img/map.png" alt=""> -->
+                <div class="item_box">
+                    <span>网点数</span>
+                    <div>
+                        <i></i>
+                        <h2>{{ healthSummary.total }}</h2>
+                    </div>
+                </div>
+                <div class="item_box">
+                    <span>已检</span>
+
+                    <div>
+                        <i></i>
+                        <h2>{{ healthSummary.checkedCount }}</h2>
+                    </div>
+                </div>
+                <div class="item_box">
+                    <span>90分以上</span>
+                    <div>
+                        <i></i>
+                        <h2>{{ healthSummary.over90Count }}</h2>
+                    </div>
+                </div>
+                <div class="item_box">
+                    <span>90及以下</span>
+                    <div>
+                        <i></i>
+                        <h2>{{ healthSummary.notover90Count }}</h2>
+                    </div>
+                </div>
+            </main>
+
+            <header class="t_b_h_1">
+                <span>网点健康度检查TOP3</span>
+            </header>
+            <main class="t_b_m_1" style="top:70%">
+                <div v-for="(item, index) in healthRanking" :key="index">
+                    <i>
+                        <t>{{ index + 1 }}</t>
+                    </i> {{ item.orgName }} {{ parseFloat(item.score).toFixed(2) }}分
+                </div>
+            </main>
+        </div>
+    </div>
+</template>
+<script>
+import { deviceOnline, deviceHealth } from "@/api/iot/board";
+
+export default {
+    props: {
+        orgId: {
+            type: String,
+            isRequired: true,
+        },
+    },
+    data() {
+        return {
+            chartData: {
+                total: [],
+                onLineCount: [],
+                name: [],
+            },
+            healthSummary: {
+                total: 0,
+                checkedCount: 0,
+                over90Count: 0,
+                notover90Count: 0,
+            },
+            healthRanking: [],
+            isMouseOver: false
+        };
+    },
+
+    components: {},
+
+    computed: {},
+
+    watch: {
+        orgId: {
+            deep: true,
+            handler(val) {
+                this.resetTimer();
+                this.getData();
+            },
+        },
+        chartData: {
+            deep: true,
+            handler() {
+                this.initMap();
+            },
+        },
+    },
+
+    created() {
+        this.refreshTime = 1 * 10 * 1000;
+        this.isMouseOver = false;
+    },
+
+    async mounted() {
+        window.addEventListener("resize", this.windowResize);
+    },
+    beforeDestroy() {
+        this.timer && clearInterval(this.timer);
+        this.timer = null;
+
+        window.removeEventListener("resize", this.windowResize);
+    },
+
+    methods: {
+        handleMouseEnter() {
+            this.isMouseOver = true;
+        },
+        handleMouseLeave() {
+            this.isMouseOver = false;
+        },
+        async getData() {
+            deviceOnline(this.orgId).then(r => {
+                let data = r.data;
+                let chartData = {
+                    total: [],
+                    onLineCount: [],
+                    name: [],
+                };
+
+                for (let item of data) {
+                    chartData.total.push(item.deviceCount);
+                    chartData.onLineCount.push(item.completedCount);
+                    // chartData.rate.push((item.completedRate * 100).toFixed(2));
+                    chartData.name.push(item.orgName);
+                }
+                this.chartData = chartData;
+            });
+
+            deviceHealth(this.orgId).then(r => {
+                this.healthSummary = r.data.healthSummary;
+                this.healthRanking = r.data.healthRanking
+            })
+        },
+
+        windowResize() {
+            this.myChart && this.myChart.resize();
+        },
+        initMap() {
+            let c = this.$refs["chart"];
+
+            // 基于准备好的dom,初始化echarts实例
+            this.myChart = echarts.init(
+                c
+                // document.getElementById("commAlarmEvent_Chart")
+            );
+            // var data = [70, 34, 60, 78, 69];
+            // var titlename = [
+            //     "监控主机",
+            //     "报警主机",
+            //     "动环主机",
+            //     "对讲主机",
+            //     "门禁主机",
+            // ];
+            // var valdata = [702, 406, 664, 793, 505];
+            var myColor = ["#1089E7", "#F57474", "#56D0E3", "#F8B448"];
+            option = {
+                title: {
+                    text: "设备在线率",
+                    x: "center",
+                    textStyle: {
+                        color: "#FFF",
+                    },
+                    left: "6%",
+                    top: "10%",
+                },
+                //图标位置
+                grid: {
+                    top: "20%",
+                    left: "32%",
+                },
+                xAxis: {
+                    show: false,
+                },
+                yAxis: [
+                    {
+                        show: true,
+                        data: this.chartData.name,
+                        inverse: true,
+                        axisLine: {
+                            show: false,
+                        },
+                        splitLine: {
+                            show: false,
+                        },
+                        axisTick: {
+                            show: false,
+                        },
+                        axisLabel: {
+                            color: "#fff",
+                            formatter: (value, index) => {
+                                return [`{lg|${index + 1}}  ` + "{title|" + value + "} "].join(
+                                    "\n"
+                                );
+                            },
+                            rich: {
+                                lg: {
+                                    backgroundColor: "#339911",
+                                    color: "#fff",
+                                    borderRadius: 15,
+                                    // padding: 5,
+                                    align: "center",
+                                    width: 15,
+                                    height: 15,
+                                },
+                            },
+                        },
+                    },
+                    {
+                        show: true,
+                        inverse: true,
+                        data: this.chartData.total,
+                        axisLabel: {
+                            textStyle: {
+                                fontSize: 12,
+                                color: "#fff",
+                            },
+                        },
+                        axisLine: {
+                            show: false,
+                        },
+                        splitLine: {
+                            show: false,
+                        },
+                        axisTick: {
+                            show: false,
+                        },
+                    },
+                ],
+                series: [
+                    {
+                        name: "条",
+                        type: "bar",
+                        yAxisIndex: 0,
+                        data: this.chartData.onLineCount,
+                        barWidth: 10,
+                        itemStyle: {
+                            normal: {
+                                barBorderRadius: 20,
+                                color: function (params) {
+                                    var num = myColor.length;
+                                    return myColor[params.dataIndex % num];
+                                },
+                            },
+                        },
+                        label: {
+                            normal: {
+                                show: true,
+                                position: "inside",
+                                formatter: "{c}%",
+                            },
+                        },
+                    },
+                    {
+                        name: "框",
+                        type: "bar",
+                        yAxisIndex: 1,
+                        barGap: "-100%",
+                        data: [100, 100, 100, 100, 100],
+                        barWidth: 15,
+                        itemStyle: {
+                            normal: {
+                                color: "none",
+                                borderColor: "#00c1de",
+                                borderWidth: 3,
+                                barBorderRadius: 15,
+                            },
+                        },
+                    },
+                ],
+            };
+            // 使用刚指定的配置项和数据显示图表。
+            this.myChart.setOption(option);
+        },
+
+        resetTimer() {
+            this.timer && clearInterval(this.timer);
+            this.timer = setInterval(() => {
+                if (this.isMouseOver) {
+                    return;
+                }
+                this.getData();
+            }, this.refreshTime);
+        },
+    },
+};
+</script>
+<style scoped src="./../css/index.css"></style>
+<style lang="scss" scoped>
+.health {
+    width: 50%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    padding: 0 3%;
+
+    ::v-deep .header {
+        color: #fff;
+        width: 100%;
+        height: 12%;
+        font-size: 20px;
+    }
+
+    ::v-deep .banklet_main {
+        height: 40%;
+        width: 100%;
+    }
+
+    ::v-deep .item_box {
+        border: 1px dotted #f0ff00;
+        border-radius: 5px;
+        margin-top: 5%;
+        height: 45%;
+        width: 45%;
+        float: left;
+        display: flex;
+        flex-direction: column;
+        font-size: 14px;
+    }
+
+
+    ::v-deep .item_box:nth-child(even) {
+        margin-left: 10%;
+    }
+
+    ::v-deep .item_box>span:first-child {
+        line-height: 20px;
+    }
+
+    ::v-deep .item_box>div:last-child {
+        // display: block;
+        width: 100%;
+        height: calc(100% - 20px);
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        position: relative;
+    }
+
+    ::v-deep .item_box>div:last-child>i {
+        width: 16px;
+        height: 16px;
+        display: inline-block;
+        position: absolute;
+        left: 20%;
+    }
+
+    ::v-deep .item_box:first-child>div:last-child>i {
+        background: url("../img/t.png") no-repeat;
+        background-size: 100% 100%;
+    }
+
+    ::v-deep .item_box:nth-child(2)>div:last-child>i {
+        background: url("../img/s.png") no-repeat;
+        background-size: 100% 100%;
+    }
+
+    ::v-deep .item_box:nth-child(3)>div:last-child>i {
+        background: url("../img/j.png") no-repeat;
+        background-size: 100% 100%;
+    }
+
+    ::v-deep .item_box:nth-child(4)>div:last-child>i {
+        background: url("../img/g.png") no-repeat;
+        background-size: 100% 100%;
+    }
+}
+
+.t_b_m img {
+    position: absolute;
+    left: 52%;
+    top: 22%;
+    border-top: 1px dotted #f0ff00;
+    padding: 0 0.18rem;
+    padding-top: 20px;
+    width: 3.19rem;
+    height: 1.67rem;
+}
+
+.t_b_h_1 {
+    position: absolute;
+    font-size: 0.16rem;
+    left: 54%;
+    width: 50%;
+    height: 2.1rem;
+    top: 60%;
+}
+
+.t_b_h_1 span {
+    position: absolute;
+    color: #fff;
+    top: 10%;
+    font-size: 20px;
+}
+
+.t_b_h_1 img {
+    position: absolute;
+    width: 0.53rem;
+    height: 0.53rem;
+    top: 6%;
+    left: 24%;
+}
+
+.t_b_h_1 h3 {
+    font-size: 0.36rem;
+    color: #f0ff00;
+    position: absolute;
+    left: 55%;
+    top: 8%;
+    width: 1rem;
+}
+
+.t_b_h_1 h3 span {
+    font-size: 0.2rem;
+    position: absolute;
+    left: 50%;
+    top: 28%;
+    color: #0072ff;
+}
+
+.t_b_m_1 {
+    position: absolute;
+    font-size: 0.16rem;
+    left: 54%;
+    width: 50%;
+    height: 2.1rem;
+    top: 70%;
+}
+
+.t_b_m_1 div {
+    margin-top: 15px;
+    height: 20px;
+    color: white;
+    font-size: 14px;
+}
+
+.t_b_m_1 div>i {
+    background-color: #339911;
+    font-family: 仿宋体;
+    width: 19px;
+    display: inline-block;
+    border-radius: 9.5px;
+}
+
+.t_b_m_1 div>i>t {
+    left: 3px;
+    position: relative;
+}
+
+.t_b_box,
+.t_b_box1,
+.t_b_box2,
+.t_b_box3 {
+    width: 35%;
+    height: 10%;
+
+    position: absolute;
+}
+
+.t_b_box {
+    top: 25%;
+    left: 56%;
+}
+
+.t_b_box span,
+.t_b_box1 span,
+.t_b_box2 span,
+.t_b_box3 span {
+    font-size: 0.14rem;
+    color: #fff;
+    position: absolute;
+    left: 10%;
+}
+
+.t_b_box i,
+.t_b_box1 i,
+.t_b_box2 i,
+.t_b_box3 i {
+    width: 20px;
+    height: 20px;
+    position: absolute;
+    top: 50%;
+    left: 15%;
+}
+
+
+
+.t_b_box h2,
+.t_b_box1 h2,
+.t_b_box2 h2,
+.t_b_box3 h2 {
+    font-size: 0.18rem;
+    color: #fff;
+    position: absolute;
+    top: 30%;
+    left: 40%;
+}
+
+.t_b_box1 {
+    top: 25%;
+    left: 78%;
+}
+
+.t_b_box2 {
+    top: 45%;
+    left: 56%;
+}
+
+.t_b_box3 {
+    top: 45%;
+    left: 78%;
+}
+</style>

+ 114 - 0
src/views/iot/board/components/protection.vue

@@ -0,0 +1,114 @@
+<template>
+    <div class="component_box">
+        <ul class="t_nav">
+            <li>
+                <span>报警控制器</span>
+                <h1>{{ info.total }}</h1>
+                <i></i>
+            </li>
+            <li>
+                <span>布防数</span>
+                <h1>{{ info.on }}</h1>
+                <i></i>
+            </li>
+            <li>
+                <span>撤防数</span>
+                <h1>{{ info.off }}</h1>
+            </li>
+        </ul>
+    </div>
+</template>
+<script>
+import { protectionCount } from '@/api/iot/board'
+export default {
+    data() {
+        return {
+            info: {
+                total: 0,
+                on: 0,
+                off: 0
+            },
+        }
+    },
+    props: {
+        orgId: {
+            type: String,
+            isRequired: true,
+        }
+    },
+    watch: {
+        orgId: {
+            deep: true,
+            handler(val) {
+                this.resetTimer();
+                this.getData();
+            },
+        }
+    },
+    created() {
+        this.refreshTime = 1 * 10 * 1000;
+        this.isMouseOver = false;
+    },
+    methods: {
+        getData() {
+            protectionCount(this.orgId).then(r => {
+                this.info = r.data;
+            })
+        },
+        beforeDestroy() {
+            this.timer && clearInterval(this.timer);
+            this.timer = null;
+        },
+        resetTimer() {
+            this.timer && clearInterval(this.timer);
+            this.timer = setInterval(() => {
+                this.getData();
+            }, this.refreshTime);
+        },
+    }
+}
+</script>
+<style scoped src="./../css/index.css"></style>
+<style lang="css" scoped>
+.t_nav {
+    width: 100%;
+    height: 100%;
+}
+
+.t_nav li {
+    display: inline-block;
+    width: 30%;
+    height: 100%;
+    text-align: center;
+    position: relative;
+}
+
+.t_nav li span {
+    font-size: 20px;
+    color: #1aa1fd;
+    position: absolute;
+    left: 0;
+    right: 0;
+    margin: auto;
+    top: 20%;
+}
+
+.t_nav li h1 {
+    font-size: 20px;
+    color: #fff;
+    position: absolute;
+    left: 0;
+    right: 0;
+    margin: auto;
+    top: 70%;
+}
+
+.t_nav li i {
+    width: 1px;
+    height: 100%;
+    position: absolute;
+    right: 1px;
+    background: url("../img/sper.png") no-repeat;
+    background-size: 100% 100%;
+}
+</style>

+ 112 - 0
src/views/iot/board/css/index.css

@@ -0,0 +1,112 @@
+.body {
+    background-image: url("../img/true.png");
+    background-position: 100%;
+    background-color: rgba(8, 8, 8);
+    color: white;
+    /* text-shadow: 0 0 5px #252525; */
+    font-size: 18px;
+    width: 100%;
+    height: calc(100vh - 100px);
+    overflow: hidden;
+}
+
+.t_header {
+    width: 100%;
+    height: 80px;
+    background: url("../img/linx.png") no-repeat;
+    background-size: 100% 100%;
+}
+
+.t_header_title{
+    width: 400px;
+    height: 100%;
+    margin-left:80px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+
+}
+
+.t_header_title span {
+    color: #fff;
+    font-size: 40px;
+}
+.t_main {
+    width: 100%;
+    height: calc(100% - 80px);
+    margin: 0 auto;
+    margin-top: 0px;
+    margin-bottom: 0;
+}
+.t_main>div{
+    width: 100%;
+    height: 50%;
+    display: flex;
+    border:solid 1px #fff;
+}
+
+.t_left_box {
+    width: 18%;
+    height: 100%;
+    /* display: inline-block; */
+    /* text-align: center; */
+}
+.t_l_line {
+    position: relative;
+    top: 0;
+    left: 0;
+}
+.t_r_line {
+    position: relative;
+    bottom: 0;
+    right: 0;
+}
+.t_center_box {
+    width: 36.5%;
+    height: 100%;
+}
+
+.t_top_box {
+    width: 100%;
+    height: 110px;
+    /* height: 1.13rem; */
+    overflow: hidden;
+    /* margin-bottom: 0.2rem; */
+}
+.t_bottom_box {
+    width: 100%;
+
+    height: calc(100% - 110px);
+    overflow: hidden;
+    position: relative;
+}
+.t_right_box {
+    display: inline-block;
+    width: 45.5%;
+    height: 100%;
+    position: relative;
+}
+.b_left_box {
+    display: inline-block;
+    width: 31.6%;
+    height:100%;
+    position: relative;
+}
+.b_center_box {
+    display: inline-block;
+    width: 22.9%;
+    height: 100%;
+    position: relative;
+}
+.b_right_box {
+    display: inline-block;
+    width: 45.5%;
+    height:100%;
+    position: relative;
+}
+
+.component_box {
+    width: 100%;
+    height: calc(100% - 10px);
+}
+

BIN
src/views/iot/board/img/consumption.png


BIN
src/views/iot/board/img/end.png


BIN
src/views/iot/board/img/environment.png


BIN
src/views/iot/board/img/fire.png


BIN
src/views/iot/board/img/g.png


BIN
src/views/iot/board/img/indent.png


BIN
src/views/iot/board/img/j.png


BIN
src/views/iot/board/img/left_line.png


BIN
src/views/iot/board/img/linx.png


BIN
src/views/iot/board/img/map.png


BIN
src/views/iot/board/img/monitor.png


BIN
src/views/iot/board/img/org.png


BIN
src/views/iot/board/img/right_line.png


BIN
src/views/iot/board/img/s.png


BIN
src/views/iot/board/img/sper.png


BIN
src/views/iot/board/img/t.png


BIN
src/views/iot/board/img/true.png


BIN
src/views/iot/board/img/vip.png


+ 63 - 0
src/views/iot/board/index.vue

@@ -0,0 +1,63 @@
+<template>
+    <div class="body">
+        <header class="t_header">
+            <div class="t_header_title">
+                <span>物联监测看板</span>
+            </div>
+        </header>
+        <main class="t_main">
+            <div>
+                <layout :className="'t_left_box'">
+                    <deviceCount :orgId="orgId"></deviceCount>
+                </layout>
+                <div class="t_center_box">
+                    <layout :className="'t_top_box'" style="padding-bottom: 0px;">
+                        <protection />
+                    </layout>
+                    <layout :className="'t_bottom_box'" style="padding-top:0px">
+                        <device-map />
+                    </layout>
+                </div>
+                <layout :className="'t_right_box'">
+                    <online-and-health></online-and-health>
+                </layout>
+            </div>
+            <div>
+                <layout :className="'b_left_box'">
+                    <alarm-trend />
+                </layout>
+                <layout :className="'b_center_box'">
+                    <alarm-rate></alarm-rate>
+                </layout>
+                <layout :className="'b_right_box'">
+                    <alarm-list></alarm-list>
+                </layout>
+            </div>
+        </main>
+    </div>
+</template>
+<script>
+import { mapGetters } from "vuex";
+import layout from './components/layout.vue';
+import deviceCount from './components/deviceCount.vue';
+import protection from './components/protection.vue';
+import deviceMap from './components/deviceMap.vue';
+import onlineAndHealth from './components/onlineAndHealth.vue';
+import alarmTrend from './components/alarmTrend.vue';
+import alarmRate from './components/alarmRate.vue';
+import alarmList from './components/alarmList.vue';
+
+export default {
+    name: "iot_board",
+    components: { layout, deviceCount, protection, deviceMap, onlineAndHealth, alarmTrend, alarmRate, alarmList },
+    computed: {
+        ...mapGetters(["orgId", "depTree", "orgName",]),
+    },
+    data() {
+        return {
+            orgId: this.orgId,
+        }
+    }
+}
+</script>
+<style scoped src="./css/index.css"></style>

+ 7 - 6
src/views/iot/server/index.vue

@@ -42,11 +42,11 @@
                   />
                 </el-select>
               </el-form-item>
-              <el-form-item label="主机注册码" prop="registerCode">
+              <el-form-item label="主机激活码" prop="registerCode">
                 <el-input
                   v-model="queryParams.registerCode"
                   clearable
-                  placeholder="请输入关键字"
+                  placeholder="请输入主机激活码"
                   @keyup.enter.native="handleQuery"/>
               </el-form-item>
             </el-form>
@@ -118,7 +118,7 @@
             <el-table-column label="所属机构" align="center" prop="orgName" width="150"/>
             <el-table-column label="主机名称" align="center" prop="iotName" width="150"/>
             <el-table-column label="主机编码" align="center" prop="iotCode" width="220" :show-overflow-tooltip="true"/>
-            <el-table-column label="主机注册码" align="center" prop="registerCode" width="220"/>
+            <el-table-column label="主机激活码" align="center" prop="registerCode" width="220"/>
             <el-table-column label="主机服务IP" align="center" prop="iotIp" width="150"/>
             <el-table-column label="链接状态" align="center" prop="iotStatus" width="150">
               <template slot-scope="r"
@@ -190,10 +190,10 @@
       <el-form ref="form" :model="form" :rules="rules" label-width="110px">
         <el-row>
           <el-col :span="24">
-            <el-form-item label="主机信息" prop="iotName">
+            <el-form-item label="主机名称" prop="iotName">
               <el-input
                 v-model="form.iotName"
-                placeholder="请输入主机信息"
+                placeholder="请输入主机名称"
                 maxlength="50"
               />
             </el-form-item>
@@ -282,7 +282,7 @@ export default {
         iotStatus: null,
       },
       rules: {
-        iotName: [{required: true, message: "请输入主机信息", trigger: "blur"}],
+        iotName: [{required: true, message: "请输入主机名称", trigger: "blur"}],
         orgId: [{required: true, message: "请选择所属机构", trigger: "blur"}],
         enable: [{required: true, message: "请选择是否启用", trigger: "blur"}],
       },
@@ -368,6 +368,7 @@ export default {
       this.getDeptTree();
       this.reset();
       this.open = true;
+      this.form.enable= "0";
       this.title = "新增主机信息";
     },
     editIot() {

+ 268 - 287
src/views/system/device/index.vue

@@ -14,174 +14,91 @@
       <el-col :span="20" :xs="24">
         <div class="main-right-box">
           <div class="main-search-box">
-              <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
-                <el-form-item label="设备名称" prop="deviceName">
-                  <el-input clearable v-model="queryParams.deviceName" placeholder="请输入关键字" maxlength="50"
-                            @keyup.enter.native="handleQuery" />
-                </el-form-item>
-                <el-form-item label="设备类别" prop="assetType" label-width="80">
-
-                  <el-select style="width: 100%;"  v-model="queryParams.assetType" placeholder="请选择设备类别"
-                             @change="searchChangeSelectDevice" clearable>
-                    <el-option v-for="dict in dict.type.sys_asset_type" :key="dict.value" :label="dict.label"
-                               :value="`${dict.value}`"></el-option>
-                  </el-select>
-                </el-form-item>
-
-                <el-form-item label="设备分类" prop="deviceType" label-width="80">
-
-                  <el-select style="width: 100%;" clearable v-model="queryParams.deviceType" placeholder="请选择设备种类">
-                    <el-option v-for="item in searchDevices" :key="item.dictValue" :label="item.dictLabel"
-                               :value="item.dictValue"></el-option>
-                  </el-select>
-                </el-form-item>
-              </el-form>
-              <el-row :gutter="10">
-                <el-col :span="1.5">
-                  <el-button
-                    type="primary"
-                    icon="el-icon-search"
-                    size="mini"
-                    @click="handleQuery"
-                  >搜索</el-button
-                  >
-                </el-col>
-                <el-col :span="1.5">
-                  <el-button
-                    type="primary"
-                    icon="el-icon-refresh"
-                    size="mini"
-                    @click="resetQuery"
-
-                  >重置</el-button
-                  >
-                </el-col>
-
-
-                <el-col :span="1.5">
-                  <el-button
-                    type="primary"
-                    icon="el-icon-plus"
-                    size="mini"
-                    @click="handleAdd"
-                    v-hasPermi="['system:device:add']"
-                  >新增设备</el-button
-                  >
-                </el-col>
-
-                <el-col :span="1.5">
-                  <el-button
-                    type="primary"
-                    icon="el-icon-upload"
-                    size="mini"
-                    @click="handleImport"
-                    v-hasPermi="['system:device:importData']"
-                  >导入设备</el-button
-                  >
-                </el-col>
-
-                <el-col :span="1.5">
-                  <el-button
-                    type="primary"
-                    icon="el-icon-download"
-                    size="mini"
-                    @click="handleOut"
-                    v-hasPermi="['system:device:export']"
-                  >导出模版</el-button
-                  >
-                </el-col>
-                <right-toolbar
-                  :showSearch.sync="showSearch"
-                  @queryTable="getList"
-                ></right-toolbar>
-              </el-row>
-            </div>
-          <el-table
-            border
-            height="646"
-            size="small"
-            v-loading="loading"
-            :data="deviceList"
-            @selection-change="handleSelectionChange"
-
-          >
-          <!-- :header-cell-style="{backgroundColor:'#CCE8F7'}" -->
-            <!--<el-table-column type="selection" width="55" align="center" />-->
+            <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
+              <el-form-item label="设备名称" prop="deviceName">
+                <el-input clearable v-model="queryParams.deviceName" placeholder="请输入关键字" maxlength="50"
+                          @keyup.enter.native="handleQuery"/>
+              </el-form-item>
+              <el-form-item label="资产类别" prop="assetType" label-width="80">
+
+                <el-select style="width: 100%;" v-model="queryParams.assetType" placeholder="请选择资产类别"
+                           @change="assetSelectChange" @clear="clearAsset" clearable>
+                  <el-option v-for="item in getAssetDict('AssetDeviceType',-1)" :key="item.id" :label="item.name"
+                             :value="item.id"></el-option>
+                </el-select>
+              </el-form-item>
+
+              <el-form-item label="设备分类" prop="deviceType" label-width="80">
+                <el-select style="width: 100%;" clearable v-model="queryParams.deviceType" placeholder="请选择设备分类">
+                  <el-option v-for="item in assetChildrenDictList" :key="item.id" :label="item.name"
+                             :value="item.id"></el-option>
+                </el-select>
+              </el-form-item>
+            </el-form>
+            <el-row :gutter="10">
+              <el-col :span="1.5">
+                <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+              </el-col>
+              <el-col :span="1.5">
+                <el-button type="primary" icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+              </el-col>
+
+              <el-col :span="1.5">
+                <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd"
+                           v-hasPermi="['system:device:add']">新增设备
+                </el-button>
+              </el-col>
+
+              <el-col :span="1.5">
+                <el-button type="primary" icon="el-icon-upload" size="mini" @click="handleImport"
+                           v-hasPermi="['system:device:importData']">导入设备
+                </el-button>
+              </el-col>
+
+              <el-col :span="1.5">
+                <el-button type="primary" icon="el-icon-download" size="mini" @click="handleOut"
+                           v-hasPermi="['system:device:export']">导出模版
+                </el-button>
+              </el-col>
+              <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+            </el-row>
+          </div>
+          <el-table border height="646" size="small" v-loading="loading" :data="deviceList"
+                    @selection-change="handleSelectionChange">
             <el-table-column label="序号" align="center" min-width="50">
               <template v-slot:default="scope">
                 <span v-text="getPageIndex(scope.$index)"> </span>
               </template>
             </el-table-column>
-            <el-table-column label="地区" align="left" prop="affiliatedArea" />
-            <el-table-column label="行社" align="left" prop="affiliatedBank" />
-            <el-table-column label="所属机构" align="left" prop="orgName" />
-
-            <el-table-column
-              label="设备类别"
-              align="center"
-              key="assetType"
-              prop="assetType"
-            >
+            <el-table-column label="地区" align="left" prop="affiliatedArea"/>
+            <el-table-column label="行社" align="left" prop="affiliatedBank"/>
+            <el-table-column label="所属机构" align="left" prop="orgName"/>
+
+            <el-table-column label="设备类别" align="center" key="assetType" prop="assetType">
               <template slot-scope="scope">
-                <dict-tag
-                  :options="dict.type.sys_asset_type"
-                  :value="scope.row.assetType"
-                />
+                <dict-tag :options="dict.type.sys_asset_type" :value="scope.row.assetType"/>
               </template>
             </el-table-column>
 
-            <el-table-column
-              label="设备分类"
-              align="center"
-              key="deviceType"
-              prop="deviceType"
-            >
+            <el-table-column label="设备分类" align="center" key="deviceType" prop="deviceType">
               <template slot-scope="scope">
-                <dict-tag
-                  :options="dict.type.sys_device_type"
-                  :value="scope.row.deviceType"
-                />
+                <dict-tag :options="dict.type.sys_device_type" :value="scope.row.deviceType"/>
               </template>
             </el-table-column>
-            <el-table-column label="设备名称" align="center" prop="deviceName"  />
-            <!-- <el-table-column label="设备品牌" align="center" prop="deviceBrand" />
-            <el-table-column
-              label="有效期至"
-              align="center"
-              prop="checkTime"
-              width="160"
-            >
-            </el-table-column> -->
-            <!--    <el-table-column label="保修期限" align="center" prop="maintenanceTerm" /> -->
-            <el-table-column
-              label="操作"
-              align="center"
-              class-name="small-padding fixed-width"
-            >
+            <el-table-column label="设备名称" align="center" prop="deviceName"/>
+            <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
               <template slot-scope="scope">
-                <el-button
-                  size="mini"
-                  type="text"
-                  icon="el-icon-edit-outline"
-                  @click="handleUpdate(scope.row)"
-                  v-hasPermi="['system:device:edit']"
-                  >编辑</el-button>
-                <el-button
-                  size="mini"
-                  type="text"
-                  icon="el-icon-delete"
-                  @click="handleDelete(scope.row)"
-                  v-hasPermi="['system:device:remove']"
-                  >删除</el-button>
+                <el-button size="mini" type="text" icon="el-icon-edit-outline" @click="handleUpdate(scope.row)"
+                           v-hasPermi="['system:device:edit']">编辑
+                </el-button>
+                <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
+                           v-hasPermi="['system:device:remove']">删除
+                </el-button>
               </template>
             </el-table-column>
           </el-table>
-          <pagination
-            :total="total"
-            :page.sync="queryParams.pageNum"
-            :limit.sync="queryParams.pageSize"
-            @pagination="getList"
-          />
+          <pagination :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
+                      @pagination="getList"/>
         </div>
       </el-col>
     </el-row>
@@ -195,6 +112,7 @@
       append-to-body
     >
       <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+
         <el-row>
           <el-col :span="24">
             <el-form-item label="所属机构" prop="orgId">
@@ -214,50 +132,18 @@
             </el-form-item>
           </el-col>
         </el-row>
+
         <el-row>
           <el-col :span="12">
-            <el-form-item label="设备类别" prop="assetType">
-              <el-select
-                style="width: 100%"
-                v-model="form.assetType"
-                :popper-append-to-body="false"
-                placeholder="请选择设备类别"
-                @change="changeSelectDevice"
-              >
-                <el-option
-                  v-for="dict in dict.type.sys_asset_type"
-                  :key="dict.value"
-                  :label="dict.label"
-                  :value="`${dict.value}`"
-                ></el-option>
-              </el-select>
+            <el-form-item label="资产编号" prop="assetNo">
+              <el-input
+                v-model="form.assetNo"
+                placeholder="请输入设备名称"
+                maxlength="50"
+              />
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="设备分类" prop="deviceType">
-              <el-select
-                style="width: 100%"
-                :popper-append-to-body="false"
-                v-model="form.deviceType"
-                placeholder="请选择设备分类"
-              >
-                <el-option
-                  v-for="item in devices"
-                  :key="item.dictValue"
-                  :label="item.dictLabel"
-                  :value="item.dictValue"
-                ></el-option>
-              </el-select>
-            </el-form-item>
-          </el-col>
-
-
-
-
-        </el-row>
-        <el-row>
-
-          <el-col :span="12">
             <el-form-item label="设备名称" prop="deviceName">
               <el-input
                 v-model="form.deviceName"
@@ -266,83 +152,151 @@
               />
             </el-form-item>
           </el-col>
+        </el-row>
+
+        <el-row>
           <el-col :span="12">
-            <el-form-item label="设备品牌" prop="deviceBrand">
-              <el-input v-model="form.deviceBrand" placeholder="请输入设备品牌" maxlength="50" />
+            <el-form-item label="资产分类" prop="assetType">
+              <el-select style="width: 100%" v-model="form.assetType" :popper-append-to-body="false"
+                         placeholder="请选择资产分类" @change="assetSelectChange">
+                <el-option v-for="item in getAssetDict('AssetDeviceType',-1)" :key="item.id" :label="item.name"
+                           :value="item.id"></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="设备分类" prop="deviceType">
+              <el-select style="width: 100%" :popper-append-to-body="false" clearable v-model="form.deviceType"
+                         placeholder="请选择设备分类">
+                <el-option v-for="item in assetChildrenDictList" :key="item.id" :label="item.name"
+                           :value="item.id"></el-option>
+              </el-select>
             </el-form-item>
           </el-col>
         </el-row>
+
+
         <el-row>
           <el-col :span="12">
-            <el-form-item
-              v-if="form.deviceType == 2"
-              label="硬盘录像机"
-              prop="hostId"
-            >
-              <el-select
-                style="width: 100%"
-                v-model="form.hostId"
-                placeholder="请选择关联主机"
-              >
-                <el-option
-                  v-for="item in hostList"
-                  :key="item.id"
-                  :label="item.deviceName"
-                  :value="item.id"
-                ></el-option>
+            <el-form-item label="设备品牌" prop="deviceBrand">
+              <el-select style="width: 100%" v-model="form.deviceBrand" placeholder="请选择设备品牌"
+                         @change="brandSelectChange">
+                <el-option v-for="item in getAssetDict('BrandType',-1)" :key="item.id" :label="item.name"
+                           :value="item.id"></el-option>
               </el-select>
             </el-form-item>
           </el-col>
+          <!--        <el-row>
+                    <el-col :span="12">
+                      <el-form-item v-if="form.deviceType == 2" label="硬盘录像机" prop="hostId">
+                        <el-select style="width: 100%" v-model="form.hostId" placeholder="请选择关联主机">
+                          <el-option v-for="item in hostList" :key="item.id" :label="item.deviceName"
+                                     :value="item.id"></el-option>
+                        </el-select>
+                      </el-form-item>
+                    </el-col>
+
+                    <el-col :span="12">
+                      <el-form-item v-if="form.deviceType == 2" label="通道号" prop="channel">
+                        <el-input type="number" max="64" min="0"
+                                  oninput="if(value<=0)value=null;if(value>=64)value=64;value=parseInt(value)"
+                                  v-model="form.channel" placeholder="请输入关联通道号"/>
+                      </el-form-item>
+                    </el-col>
+                  </el-row>
+
+                  <el-row>
+                    <el-col :span="12">
+                      <el-form-item v-if="form.assetType == 0" label="有效期至" prop="checkTime">
+                        <el-date-picker style="width: 100%" clearable v-model="form.checkTime" type="date"
+                                        value-format="yyyy-MM-dd" placeholder="请选择到期时间">
+                        </el-date-picker>
+                      </el-form-item>
+                    </el-col>
+                  </el-row>-->
+          <el-col :span="12">
+            <el-form-item label="设备型号" prop="deviceModel">
+              <el-select style="width: 100%" v-model="form.deviceModel" placeholder="请选择设备型号">
+                <el-option v-for="item in brandChildrenDictList" :key="item.id" :label="item.name"
+                           :value="item.id"></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
 
+        <el-row>
           <el-col :span="12">
-            <el-form-item
-              v-if="form.deviceType == 2"
-              label="通道号"
-              prop="channel"
-            >
-              <el-input
-                type="number"
-                max="64"
-                min="0"
-                oninput="if(value<=0)value=null;if(value>=64)value=64;value=parseInt(value)"
-                v-model="form.channel"
-                placeholder="请输入关联通道号"
-              />
+            <el-form-item label="采购日期" prop="purchasingTime">
+              <el-date-picker style="width: 100%" clearable v-model="form.purchasingTime" type="date"
+                              value-format="yyyy-MM-dd" placeholder="请选择采购日期">
+              </el-date-picker>
             </el-form-item>
           </el-col>
+
           <el-col :span="12">
-            <el-form-item label="是否高清"   v-if="form.deviceType == 2" >
-                <el-switch v-model="form.definition" active-value="1" inactive-value="0"></el-switch>
-              </el-form-item>
+            <el-form-item label="安装位置" prop="address">
+              <el-input v-model="form.address" placeholder="请输入安装位置" maxlength="50"/>
+            </el-form-item>
           </el-col>
         </el-row>
 
         <el-row>
           <el-col :span="12">
-            <el-form-item
-              v-if="form.assetType == 0"
-              label="有效期至"
-              prop="checkTime"
-            >
-              <el-date-picker
-                style="width: 100%"
-                clearable
-                v-model="form.checkTime"
-                type="date"
-                value-format="yyyy-MM-dd"
-                placeholder="请选择到期时间"
-              >
+            <el-form-item label="消防类有效期" prop="checkTime">
+              <el-date-picker style="width: 100%" clearable v-model="form.checkTime" type="date"
+                              value-format="yyyy-MM-dd" placeholder="请选择消防类有效期">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="保修期限" prop="maintenanceTerm">
+              <el-date-picker style="width: 100%" clearable v-model="form.maintenanceTerm" type="date"
+                              value-format="yyyy-MM-dd" placeholder="请选择保修期限">
               </el-date-picker>
             </el-form-item>
           </el-col>
         </el-row>
+
         <el-row>
           <el-col :span="12">
-            <el-form-item label="关联登记簿"   v-if="form.deviceType == 1"  prop="inBook">
-              <el-switch v-model="form.inBook" :active-value="1" :inactive-value="0"></el-switch>
+            <el-form-item label="投入使用时间" prop="useTime">
+              <el-date-picker style="width: 100%" clearable v-model="form.useTime" type="date"
+                              value-format="yyyy-MM-dd" placeholder="请选择投入使用时间">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="资产状态" prop="deviceStatus">
+              <el-select
+                v-model="form.deviceStatus"
+                clearable
+                placeholder="请选择机构类型"
+                style="width: 100%;">
+                <el-option
+                  v-for="dict in dict.type.asset_status"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="`${dict.value}`"
+                ></el-option>
+              </el-select>
             </el-form-item>
           </el-col>
         </el-row>
+
+        <!--        <el-row>
+                  <el-col :span="12">
+                    <el-form-item label="关联登记簿" v-if="form.deviceType == 1" prop="inBook">
+                      <el-switch v-model="form.inBook" :active-value="1" :inactive-value="0"></el-switch>
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+                <el-row>
+                  <el-col :span="12">
+                    <el-form-item label="是否高清" v-if="form.deviceType == 2">
+                      <el-switch v-model="form.definition" active-value="1" inactive-value="0"></el-switch>
+                    </el-form-item>
+                  </el-col>
+                </el-row>-->
       </el-form>
       <div slot="footer" class="dialog-footer">
         <el-button type="primary" @click="submitForm">确 定</el-button>
@@ -381,28 +335,28 @@
 </template>
 
 <script>
-import { getToken } from "@/utils/auth";
+import {getToken} from "@/utils/auth";
 import orgDropDown from "../../../components/orgTree/orgDropDown.vue";
 import OrgTree from "@/components/orgTree";
 import tableList from "@/mixins/tableList";
-import { deptTreeSelect } from "@/api/system/public";
-import { getDeviceType } from "@/api/system/dict/data";
+import {deptTreeSelect} from "@/api/system/public";
+import {getDeviceType} from "@/api/system/dict/data";
 import {
-  listDevice,
-  getDevice,
-  delDevice,
   addDevice,
-  updateDevice,
+  delDevice,
+  getDevice,
+  getDictTree, getDictTreeByParentId,
   getHostByOrgId,
-  getDeviceByHost,
-  downInCharge,
+  listDevice,
+  updateDevice,
 } from "@/api/system/device";
+
 export default {
   /** 引入基础minxins*/
   mixins: [tableList],
-  dicts: ["sys_asset_type", "sys_device_type"],
+  dicts: ["sys_asset_type", "sys_device_type",'asset_status'],
   name: "Device",
-  components: { OrgTree, orgDropDown },
+  components: {OrgTree, orgDropDown},
   data() {
     return {
       checkList: [],
@@ -415,21 +369,14 @@ export default {
         label: "name",
       },
       rules: {
-        deviceName: [
-          { required: true, message: "请输入设备名称", trigger: "change" },
-        ],
-        orgId: [{ required: true, message: "请选择所属机构", trigger: "blur" }],
-        assetType: [
-          { required: true, message: '请选择资产类别', trigger: 'change' },
-        ],
-        hostId: [{ required: true, message: '请选择主机', trigger: 'change' }],
-        channel: [{ required: true, message: '请输入通道号', trigger: 'change' }],
-        deviceType: [
-          { required: true, message: "请选择设备分类", trigger: "change" },
-        ],
-        checkTime: [
-          { required: true, message: "请选择有效期", trigger: "blur" },
-        ],
+        assetNo: [{required: true, message: "请输入资产编号", trigger: "change"}],
+        deviceName: [{required: true, message: "请输入设备名称", trigger: "change"}],
+        orgId: [{required: true, message: "请选择所属机构", trigger: "blur"}],
+        assetType: [{required: true, message: '请选择资产类别', trigger: 'change'}],
+      /*  hostId: [{required: true, message: '请选择主机', trigger: 'change'}],
+        channel: [{required: true, message: '请输入通道号', trigger: 'change'}],*/
+        deviceType: [{required: true, message: "请选择设备分类", trigger: "change"}],
+        deviceStatus: [{required: true, message: "请选择资产状态", trigger: "blur"}],
       },
       // 遮罩层
       loading: true,
@@ -449,9 +396,12 @@ export default {
       // 【请填写功能名称】表格数据
       deviceList: [],
       devices: null,
-      searchDevices:null,
+      searchDevices: null,
       //主机集合
       hostList: [],
+      dictionaryTreeList: [],
+      assetChildrenDictList: [],
+      brandChildrenDictList: [],
       deviceType: 0,
 
       // 弹出层标题
@@ -487,7 +437,7 @@ export default {
         isUploading: false,
 
         // 设置上传的请求头部
-        headers: { Authorization: "Bearer " + getToken() },
+        headers: {Authorization: "Bearer " + getToken()},
         // 上传的地址
         url:
           process.env.NODE_ENV === "development"
@@ -501,12 +451,17 @@ export default {
         assetType: null,
         deviceType: null,
         deviceBrand: null,
+        deviceModel: null,
         checkTime: null,
         maintenanceTerm: null,
         hostId: null,
         channel: null,
-        definition:"1",
+        address: null,
+        definition: null,
         inBook: 0,
+        purchasingTime: null,
+        assetNo: null,
+        deviceStatus: null,
       },
       // 表单校验
 
@@ -518,9 +473,11 @@ export default {
   created() {
     this.getDeptTree();
     //this.getList();
-    this.searchChangeSelectDevice(1);
+    this.assetSelectChange(1);
+    this.initDictionaryTreeList();
   },
 
+
   watch: {
     // 根据名称筛选部门树
     deptName(val) {
@@ -541,7 +498,6 @@ export default {
       this.upload.title = "设备导入";
       this.upload.open = true;
     },
-
     // 文件上传成功处理
     handleFileSuccess(response, file, fileList) {
       this.upload.open = false;
@@ -549,10 +505,10 @@ export default {
       this.$refs.upload.clearFiles();
       this.$alert(
         "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
-          response.msg +
-          "</div>",
+        response.msg +
+        "</div>",
         "导入结果",
-        { dangerouslyUseHTMLString: true }
+        {dangerouslyUseHTMLString: true}
       );
       this.getList();
     },
@@ -594,7 +550,7 @@ export default {
       this.handleQuery();
     },
     changeSelect(val) {
-      if(!val || !val.id) return;
+      if (!val || !val.id) return;
       getHostByOrgId(val).then((response) => {
         this.form.hostId = null;
         this.hostList = response.data;
@@ -676,7 +632,7 @@ export default {
         delFlag: null,
         hostId: null,
         channel: null,
-        definition:"1",
+        definition: "1",
       };
       this.resetForm("form");
     },
@@ -688,7 +644,7 @@ export default {
     /** 重置按钮操作 */
     resetQuery() {
       this.devices = null;
-      this.searchDevices=null;
+      this.searchDevices = null;
       this.resetForm("queryForm");
       this.handleQuery();
     },
@@ -717,14 +673,38 @@ export default {
         });
       }
     },
-    searchChangeSelectDevice(val) {
-      if (val) {
-        getDeviceType(val).then(response => {
-          this.searchDevices = response.data;
-          this.form.deviceType = null;
-          this.queryParams.deviceType = null;
-        })
-      }
+    //获取字典数据
+    initDictionaryTreeList() {
+      getDictTree().then((response) => {
+        this.dictionaryTreeList = response.data;
+      });
+    },
+    //从基础数据中获取资产分类
+    getAssetDict(type, parentId) {
+      let arr = []
+      this.dictionaryTreeList.filter(item => item.type === type && item.parentId == parentId).map(item => {
+        arr.push(item);
+      });
+      return arr;
+    },
+    assetSelectChange(val) {
+      //改成数据库查询, children里面
+      if (!val) return;
+      this.form.deviceType = null;
+      getDictTreeByParentId(val).then((response) => {
+        this.assetChildrenDictList = response.data;
+      });
+    },
+    brandSelectChange(val) {
+      //改成数据库查询, children里面
+      if (!val) return;
+      this.form.deviceModel = null;
+      getDictTreeByParentId(val).then((response) => {
+        this.brandChildrenDictList = response.data;
+      });
+    },
+    clearAsset() {
+      this.queryParams.deviceType = null;
     },
     /** 修改按钮操作 */
     handleUpdate(row) {
@@ -732,7 +712,7 @@ export default {
       const id = row.id || this.ids;
       getDevice(id).then((response) => {
         this.form = response.data;
-       // this.form.inBook=response.data.inBook.toString();
+        // this.form.inBook=response.data.inBook.toString();
         this.devices = response.devices;
         this.hostList = response.hostList;
         this.open = true;
@@ -772,7 +752,8 @@ export default {
           this.getList();
           this.$modal.msgSuccess("删除成功");
         })
-        .catch(() => {});
+        .catch(() => {
+        });
     },
     // 提交上传文件
     submitFileForm() {