dedsudiyu 9 maanden geleden
bovenliggende
commit
fdbe1f3b21

+ 9 - 0
package-lock.json

@@ -6415,6 +6415,15 @@
       "integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==",
       "dev": true
     },
+    "mpegts.js": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmmirror.com/mpegts.js/-/mpegts.js-1.7.3.tgz",
+      "integrity": "sha512-kqZ1C1IsbAQN72cK8vMrzKeM7hwrwSBbFAwVAc7PPweOeoZxCANrc7fAVDKMfYUzxdNkMTnec9tVmlxmKZB0TQ==",
+      "requires": {
+        "es6-promise": "^4.2.5",
+        "webworkify-webpack": "^2.1.5"
+      }
+    },
     "mqtt": {
       "version": "4.3.7",
       "resolved": "https://registry.npmmirror.com/mqtt/-/mqtt-4.3.7.tgz",

+ 1 - 0
package.json

@@ -17,6 +17,7 @@
     "jquery": "^3.6.1",
     "js-cookie": "^3.0.5",
     "js-md5": "^0.8.3",
+    "mpegts.js": "^1.7.3",
     "mqtt": "^4.2.8",
     "node-sass": "^7.0.1",
     "qs": "^6.11.0",

+ 62 - 0
src/api/index.js

@@ -245,4 +245,66 @@ export function systemBuildingGetTreeList(data) {
         data: data
     })
 }
+//应急处置-获取楼层-智能物联设备列表
+export function iotBigViewDeviceFindByType(data) {
+    return request({
+        url: '/iot/bigView/device/findByType',
+        method: 'post',
+        data: data
+    })
+}
+
+/*
+应急处置-指定物联设备查询列表
+typeKey:'camera'//摄像头
+楼层或实验室 floorId 楼层ID  subjectId  实验室ID
+*/
+export function iotBigViewDeviceList(data) {
+    return request({
+        url: '/iot/bigView/device/list',
+        method: 'post',
+        data: data
+    })
+}
+
+//应急处置-查询实验室传感器列表
+export function iotBigViewDeviceFindBySubId(query) {
+    return request({
+        url: '/iot/bigView/device/findBySubId',
+        method: 'get',
+        params: query
+    })
+}
+//执行记录-详情
+export function laboratoryEventFindByEventId(query) {
+    return request({
+        url: '/laboratory/event/findByEventId',
+        method: 'get',
+        params: query
+    })
+}
+//实验室-详情
+export function laboratorySubRelInfoGetDetailInfo(query) {
+    return request({
+        url: '/laboratory/subRelInfo/getDetailInfo',
+        method: 'get',
+        params: query
+    })
+}
+//应急处置-喇叭播放文本
+export function iotBigViewSpeakerPlayText(query) {
+    return request({
+        url: '/iot/bigView/speaker/playText',
+        method: 'get',
+        params: query
+    })
+}
 
+//应急处置-结束预案
+export function laboratoryPlanCloseRiskPlan(query) {
+    return request({
+        url: '/laboratory/plan/closeRiskPlan',
+        method: 'get',
+        params: query
+    })
+}

File diff suppressed because it is too large
+ 267 - 0
src/components/mpegtsVideo/mpegtsVideo.vue


File diff suppressed because it is too large
+ 448 - 0
src/components/personnelAdmittanceECharts/personnelAdmittanceECharts.vue


+ 855 - 0
src/components/planAlarm/planAlarm.vue

@@ -0,0 +1,855 @@
+<template>
+    <div class="planAlarm">
+        <div class="planAlarmBlack" v-if="showType">
+            <div class="planAlarm-max-big-box">
+                <div class="planAlarm-title-box">
+                    <p class="top-name-p">预警事件详情</p>
+                    <p class="top-out-p el-icon-close" @click="outPlan"></p>
+                </div>
+                <div class="planAlarm-name-box">
+                    <div class="lv-box"
+                         :class="planData.riskPlanLevel == 1?'type-color-a':(planData.riskPlanLevel == 2?'type-color-b':(planData.riskPlanLevel == 3?'type-color-c':(planData.riskPlanLevel == 4?'type-color-d':'')))">
+                        <div>{{planData.riskPlanLevel == 1?'低风险':(planData.riskPlanLevel ==
+                            2?'中风险':(planData.riskPlanLevel == 3?'较高风险':(planData.riskPlanLevel == 4?'高风险':'')))}}
+                        </div>
+                    </div>
+                    <p class="name-p">{{subData.subName}}{{subData.roomNum?'
+                        ('+subData.roomNum+')':''}}:{{planData.eventName}}</p>
+                    <p class="time-p">报警时间:{{parseTime(planData.eventStartTime)}}</p>
+                </div>
+                <div v-if="!lookImgType" class="planAlarm-big-box">
+                    <div class="planAlarm-left-box">
+                        <div class="video-box">
+                            <mpegts-video style="display: inline-block" :videoProps="item"
+                                          v-for="(item,index) in videoList" :key="index"></mpegts-video>
+                            <p class="null-video-p" v-if="!videoList[0]">实验室未配置摄像头</p>
+                        </div>
+                        <div class="bugle-box">
+                            <div class="bugle-for-button-box planAlarm-scrollbar">
+                                <p class="for-button-box" @click="clickLoudspeaker(item)"
+                                   :class="checkLoudspeaker == item.deviceNo?'for-button-box-check':''"
+                                   v-for="(item,index) in loudspeakerList" :key="index">
+                                    {{item.deviceName}}
+                                </p>
+                            </div>
+                            <div class="bugle-for-text-box planAlarm-scrollbar">
+                                <p class="null-p" v-if="!loudspeakerTextList[0]">历史发送记录</p>
+                                <div class="for-text-box" v-for="(item,index) in loudspeakerTextList" :key="index">
+                                    <p>{{item.time}}</p>
+                                    <p>{{item.value}}</p>
+                                </div>
+                            </div>
+                            <div class="bugle-for-input-box">
+                                <el-input placeholder="请输入内容" v-model="loudspeakerInput" class="input-with-select">
+                                    <p slot="append" style="cursor: pointer" @click="iotBigViewSpeakerPlayText">发送</p>
+                                </el-input>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="planAlarm-right-box">
+                        <div class="planAlarm-text-box">
+                            <div class="planAlarm-text-left-box planAlarm-scrollbar">
+                                <div>
+                                    <p>所属单位:</p>
+                                    <p>{{subData.deptName}}</p>
+                                </div>
+                                <div>
+                                    <p>所在位置:</p>
+                                    <p>
+                                        {{subData.buildName}}{{subData.floorName?'-'+subData.floorName:''}}{{subData.roomNum?'-'+subData.roomNum:''}}</p>
+                                </div>
+                                <div>
+                                    <p>实验室负责人:</p>
+                                    <p>{{subData.adminName}}</p>
+                                </div>
+                                <div>
+                                    <p>实验室安全员:</p>
+                                    <p><span v-for="(item,index) in subData.safeUserList" :key="index">{{index == 0 ?item.safeUserName:','+item.safeUserName}}</span>
+                                    </p>
+                                </div>
+                            </div>
+                            <div class="planAlarm-text-right-box planAlarm-scrollbar">
+                                <div class="box-one">
+                                    <p>持续时间:</p>
+                                    <p>{{convertSecondsToHMS(seconds)}}</p>
+                                </div>
+                                <div class="box-one">
+                                    <p>实验室内人员:</p>
+                                    <p>{{internalPerson}}</p>
+                                </div>
+                                <div class="box-two">
+                                    <p class="box-tile-p">预警通知:</p>
+                                    <div class="box-two-box">
+                                        <div class="box-two-box-min" v-if="messageType">
+                                            <div>
+                                                <p class="el-icon-check"></p>
+                                                <p>短信通知</p>
+                                            </div>
+                                        </div>
+                                        <div class="box-two-box-min" v-if="voiceType">
+                                            <div>
+                                                <p class="el-icon-check"></p>
+                                                <p>报警电话</p>
+                                            </div>
+                                        </div>
+                                        <div class="box-two-box-min">
+                                            <div>
+                                                <p class="el-icon-check"></p>
+                                                <p>企业微信</p>
+                                            </div>
+                                        </div>
+                                        <!--<div class="box-two-box-min">-->
+                                        <!--<div>-->
+                                        <!--<p class="el-icon-check"></p>-->
+                                        <!--<p>声光报警</p>-->
+                                        <!--</div>-->
+                                        <!--</div>-->
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="planAlarm-sensor-box planAlarm-scrollbar">
+                            <div v-for="(item,index) in monitorList" :key="index">
+                                <p :class="item.type?'checkColor':''">
+                                    {{item.deviceValue?item.deviceValue:'-'}}{{item.unit?item.unit:''}}</p>
+                                <p>{{item.deviceName}}</p>
+                            </div>
+                        </div>
+                        <div class="planAlarm-img-box">
+                            <p class="img-title-p">报警抓拍</p>
+                            <!--<div class="for-max-box" v-if="imgList[0]">-->
+                            <div class="for-max-box">
+                                <img :src="item" @click="lookImgButton(true,item)"
+                                     v-for="(item,index) in photographList" :key="index">
+                            </div>
+                            <p class="img-null-p" v-if="!photographList[0]">无抓拍照片</p>
+                        </div>
+                    </div>
+                </div>
+                <div v-if="lookImgType" class="planAlarm-big-box">
+                    <img class="lookImg" :src="lookImgUrl">
+                </div>
+                <div class="planAlarm-bottom-button-box">
+                    <p class="null-p"></p>
+                    <p class="button-out-p" @click="outPlan">关闭</p>
+                    <p class="button-finish-p" v-if="!lookImgType" @click="overPlan">结束预案</p>
+                    <p class="null-p"></p>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+    import {
+        iotBigViewDeviceFindByType,
+        iotBigViewDeviceList,
+        iotBigViewDeviceFindBySubId,
+        laboratoryEventFindByEventId,
+        laboratorySubRelInfoGetDetailInfo,
+        iotBigViewSpeakerPlayText,
+        laboratoryPlanCloseRiskPlan,
+    } from "@/api/index";
+    import mpegtsVideo from '@/components/mpegtsVideo/mpegtsVideo.vue'
+
+    export default {
+        name: 'planAlarm',
+        components: {
+            mpegtsVideo,
+        },
+        data() {
+            return {
+                showType: false,
+                //预案MQTT
+                planOpic: 'lab/risk/plan/change',
+                planClient: {},
+                //预案参数
+                planData: {},
+                //实验室数据
+                subData: {},
+                //实验室人数
+                internalPerson: {},
+                //实验室人数
+                userList: [],
+                //摄像头
+                videoList: [],
+                //持续时间
+                seconds: null,
+                //定时器
+                timer: null,
+                //抓拍照片
+                lookImgType: false,
+                lookImgUrl: '',
+                photographList: [],
+                //传感器
+                monitorList: [],
+                planSensorList: [],
+                //文字转语音
+                loudspeakerInput: '',
+                loudspeakerTextList: [],
+                loudspeakerList: [],
+                checkLoudspeaker: '',
+                //语音报警
+                voiceType: false,
+                //短信报警
+                messageType: false,
+            }
+        },
+        created() {
+
+        },
+        mounted() {
+
+        },
+        methods: {
+            //查询当前正在发生的预案
+            initialize(item) {
+                clearInterval(this.timer);
+                let planData = {
+                    buildId: item.buildId,
+                    floorId: item.floorId,
+                    subId: item.subId,
+                    infoId: item.infoId,
+                    eventId: item.eventId,
+                    eventName: item.eventName,
+                    riskPlanLevel: item.riskPlanLevel,
+                    eventStartTime: item.eventStartTime,
+                    eventStartTimestamp: item.eventStartTimestamp,
+                };
+                this.$set(this, 'planData', planData);
+                //传感器
+                let planSensorList = [];
+                item.triggerUploadData.forEach((minItem) => {
+                    planSensorList.push(minItem.deviceNo)
+                });
+                this.$set(this, 'planSensorList', planSensorList);
+                this.$nextTick(() => {
+                    Promise.all([
+                        //查询实验室喇叭
+                        this.iotBigViewDeviceFindByType(),
+                        //查询实验室摄像头
+                        this.iotBigViewDeviceList(),
+                        //查询实验室传感器
+                        this.iotBigViewDeviceFindBySubId(),
+                        //查询预案详情
+                        this.laboratoryEventFindByEventId(),
+                        //查询实验室详情
+                        this.laboratorySubRelInfoGetDetailInfo(),
+                    ]).then((result) => {
+                        this.$nextTick(() => {
+                            this.newTimestamp(planData.eventStartTimestamp);
+                            this.$set(this, 'showType', true);
+                        })
+                    }).catch((error) => {
+                    })
+                })
+            },
+            //查看/关闭抓拍照片
+            lookImgButton(type, item) {
+                if (type) {
+                    this.$set(this, 'lookImgUrl', item)
+                    this.$set(this, 'lookImgType', true)
+                } else {
+                    this.$set(this, 'lookImgUrl', '')
+                    this.$set(this, 'lookImgType', false)
+                }
+            },
+            //关闭窗口
+            outPlan() {
+                let self = this;
+                if (this.lookImgType) {
+                    this.$set(this, 'lookImgType', false);
+                } else {
+                    clearInterval(self.timer);
+                    self.$set(self, 'showType', false);
+                }
+            },
+            //结束预案
+            overPlan() {
+                let self = this;
+                this.$confirm('传感器数据监测异常,确定要强制结束预案?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    laboratoryPlanCloseRiskPlan({eventId: self.planData.eventId}).then(response => {
+                        self.$set(self, 'showType', false);
+                    });
+                }).catch(() => {
+                });
+            },
+            //选中喇叭
+            clickLoudspeaker(item) {
+                if (this.checkLoudspeaker != item.deviceNo) {
+                    this.$set(this, 'checkLoudspeaker', item.deviceNo);
+                } else {
+                    this.$set(this, 'checkLoudspeaker', null);
+                }
+            },
+            //发送文字转语音
+            iotBigViewSpeakerPlayText() {
+                if (!this.loudspeakerInput) {
+                    this.msgError('请输入内容')
+                    return
+                } else if (!this.checkLoudspeaker) {
+                    this.msgError('请选择喇叭')
+                    return
+                }
+                let obj = {
+                    text: this.loudspeakerInput,
+                    deviceNo: this.checkLoudspeaker,
+                }
+                iotBigViewSpeakerPlayText(obj).then(response => {
+                    let s = new Date().getHours()
+                    let f = new Date().getMinutes() < 10 ? '0' + new Date().getMinutes() : new Date().getMinutes()
+                    this.loudspeakerTextList.push({
+                        time: s + ':' + f,
+                        value: this.loudspeakerInput,
+                    })
+                    this.$set(this, 'loudspeakerInput', '');
+                })
+            },
+            //查询实验室喇叭
+            iotBigViewDeviceFindByType() {
+                let floorObj = {
+                    passageway: this.planData.floorId,
+                    typeKeyList: ['horn']
+                }
+                iotBigViewDeviceFindByType(floorObj).then(floorResponse => {
+                    let subjectObj = {
+                        subjectId: this.planData.subId,
+                        typeKeyList: ['horn']
+                    }
+                    iotBigViewDeviceFindByType(subjectObj).then(subjectResponse => {
+                        this.$set(this, 'loudspeakerList', floorResponse.data.concat(subjectResponse.data));
+                    })
+                })
+            },
+            //查询实验室摄像头
+            iotBigViewDeviceList() {
+                let obj = {
+                    page: 1,
+                    pageSize: 1,
+                    subjectId: this.planData.subId,
+                    typeKey: 'camera'
+                };
+                iotBigViewDeviceList(obj).then(response => {
+                    let list = [];
+                    response.data.records.forEach((item) => {
+                        let obj = JSON.parse(item.reservedField)
+                        if (obj.url) {
+                            item.width = 645;
+                            item.height = 363;
+                            item.type = 'flv';
+                            item.isLive = true;
+                            item.url = '';
+                            list.push(item);
+                        }
+                    })
+                    this.$set(this, 'videoList', list);
+                })
+            },
+            //查询实验室传感器
+            iotBigViewDeviceFindBySubId() {
+                let self = this;
+                iotBigViewDeviceFindBySubId({subId: this.planData.subId}).then(response => {
+                    response.data.forEach((item) => {
+                        let num = 0;
+                        self.planSensorList.forEach((minItem) => {
+                            if (item.deviceNo == minItem) {
+                                num++
+                            }
+                        })
+                        item.type = num != 0;
+                        item.icon = item.icon ? localStorage.getItem('fileBrowseEnvironment') + item.icon : null;
+                    })
+                    this.$set(this, 'monitorList', response.data);
+                })
+            },
+            //预案详情
+            laboratoryEventFindByEventId() {
+                laboratoryEventFindByEventId({eventId: this.planData.eventId}).then(response => {
+                    if (response.data.recordPhoto) {
+                        this.$set(this, 'photographList', response.data.recordPhoto.split(','));
+                    }
+                    let num1 = 0;
+                    let num2 = 0;
+                    for (let i = 0; i < response.data.messageLogVoList.length; i++) {
+                        if (response.data.messageLogVoList[i].alarmType == 1) {
+                            num1++
+                        } else if (response.data.messageLogVoList[i].alarmType == 2) {
+                            num2++
+                        }
+                    }
+                    this.$set(this, 'voiceType', num1 == 0 ? false : true);
+                    this.$set(this, 'messageType', num2 == 0 ? false : true);
+                    this.$set(this, 'internalPerson', response.data.internalPerson);
+                })
+            },
+            //实验室详情
+            laboratorySubRelInfoGetDetailInfo() {
+                laboratorySubRelInfoGetDetailInfo({infoId: this.planData.infoId}).then(response => {
+                    this.$set(this, 'subData', response.data)
+                })
+            },
+            //计算时间戳
+            newTimestamp(value) {
+                let timestamp = this.accSub(this.accDiv(Date.parse(new Date()), 1000), value);
+                this.time(timestamp);
+                console.log('timestamp', timestamp)
+            },
+            //定时器
+            time(time) {
+                let self = this;
+                self.seconds = parseInt(time);
+                self.timer = window.setInterval(refreshCount, 1000);
+
+                function refreshCount() {
+                    self.seconds++
+                }
+            },
+            //时间格式
+            convertSecondsToHMS(seconds) {
+                var hours = Math.floor(seconds / 3600);
+                var minutes = Math.floor((seconds % 3600) / 60);
+                var remainingSeconds = seconds % 60;
+                return hours + "小时 " + minutes + "分钟 " + remainingSeconds + "秒";
+            },
+        },
+    }
+</script>
+<style scoped lang="scss">
+    .planAlarm {
+        *{
+            margin:0;
+            padding:0;
+        }
+        .planAlarmBlack {
+            height: 100%;
+            width: 100%;
+            position: absolute;
+            top: 0;
+            left: 0;
+            z-index: 1000;
+            background-color: rgba(0, 0, 0, 0.8);
+            .planAlarm-max-big-box {
+                position: absolute;
+                left: 50%;
+                top: 50%;
+                margin-top: -387px;
+                margin-left: -697px;
+                width: 1394px;
+                height: 775px;
+                display: flex;
+                flex-direction: column;
+                .planAlarm-title-box {
+                    display: flex;
+                    border-bottom: 1px solid #1ed0f8;
+                    background-color: #01232A;
+                    border-top-left-radius: 10px;
+                    border-top-right-radius: 10px;
+                    .top-name-p {
+                        flex: 1;
+                        line-height: 60px;
+                        height: 60px;
+                        color: #fff;
+                        font-size: 18px;
+                        margin-left: 30px;
+                    }
+                    .top-out-p {
+                        cursor: pointer;
+                        font-size: 20px;
+                        line-height: 60px;
+                        height: 60px;
+                        color: #fff;
+                        margin-right: 30px;
+                    }
+                }
+                .planAlarm-name-box {
+                    height: 60px;
+                    display: flex;
+                    padding: 0 20px;
+                    background-color: #01232A;
+                    .lv-box {
+                        margin-top: 15px;
+                        width: 100px;
+                        height: 30px;
+                        border-radius: 50px;
+                        div {
+                            margin: 2px 2px;
+                            width: 96px;
+                            height: 26px;
+                            line-height: 26px;
+                            font-size: 16px;
+                            text-align: center;
+                            border-radius: 50px;
+                        }
+                    }
+                    .type-color-a {
+                        border: 1px solid #CCE6FE;
+                        div {
+                            background-color: #CCE6FE;
+                            color: #0183FA;
+                        }
+                    }
+                    .type-color-b {
+                        border: 1px solid rgb(256, 232, 206);
+                        div {
+                            background-color: rgb(256, 232, 206);
+                            color: #FF9900;
+                        }
+                    }
+                    .type-color-c {
+                        border: 1px solid rgb(251, 228, 206);
+                        div {
+                            background-color: rgb(251, 228, 206);
+                            color: #FF4800;
+                        }
+                    }
+                    .type-color-d {
+                        border: 1px solid rgb(248, 206, 205);
+                        div {
+                            background-color: rgb(248, 206, 205);
+                            color: #FF0000;
+                        }
+                    }
+                    .name-p {
+                        width: 450px;
+                        font-size: 16px;
+                        line-height: 60px;
+                        color: #fff;
+                        margin:0 0 0 20px;
+                    }
+                    .time-p {
+                        width: 450px;
+                        font-size: 16px;
+                        line-height: 60px;
+                        color: #fff;
+                        margin:0 0 0 20px;
+                    }
+                }
+                .planAlarm-big-box {
+                    flex: 1;
+                    display: flex;
+                    padding: 10px 10px 0;
+                    background-color: #01232A;
+                    border-bottom-left-radius: 10px;
+                    border-bottom-right-radius: 10px;
+                    .planAlarm-left-box {
+                        width: 645px;
+                        height: 599px;
+                        margin-right: 10px;
+                        border-radius: 10px;
+                        .video-box {
+                            width: 645px;
+                            height: 363px;
+                            .null-video-p {
+                                line-height: 363px;
+                                text-align: center;
+                                font-size: 16px;
+                                color: #999;
+                            }
+                        }
+                    }
+                    .bugle-box {
+                        width: 645px;
+                        height: 210px;
+                        margin-top: 10px;
+                        border-radius: 10px;
+                        background-color: #032C32;
+                        display: flex;
+                        flex-direction: column;
+                        .bugle-for-button-box {
+                            padding: 10px 10px 10px;
+                            .for-button-box-check {
+                                border: 1px solid #24D1F9 !important;
+                                color: #24D1F9 !important;
+                            }
+                            .for-button-box {
+                                display: inline-block;
+                                margin: 0 22px 11px 0;
+                                cursor: pointer;
+                                width: 120px;
+                                padding: 0 10px;
+                                height: 30px;
+                                border: 1px solid #1E768E;
+                                text-align: center;
+                                font-size: 14px;
+                                line-height: 30px;
+                                border-radius: 5px;
+                                color: #fff;
+                                /*单行省略号*/
+                                overflow: hidden;
+                                text-overflow: ellipsis;
+                                white-space: nowrap;
+                            }
+                        }
+                        .bugle-for-text-box {
+                            flex: 1;
+                            padding: 10px 10px;
+                            .null-p {
+                                color: #999;
+                                font-size: 16px;
+                                text-align: center;
+                            }
+                            .for-text-box {
+                                display: flex;
+                                p:nth-child(1) {
+                                    line-height: 24px;
+                                    font-size: 14px;
+                                    color: #24D1F9;
+                                    margin-bottom: 5px;
+                                    margin-right: 10px;
+                                }
+                                p:nth-child(2) {
+                                    line-height: 24px;
+                                    font-size: 14px;
+                                    color: #fff;
+                                    margin-bottom: 5px;
+                                }
+                            }
+                        }
+                        .bugle-for-input-box {
+                            margin: 20px;
+                        }
+                        ::v-deep .bugle-for-input-box {
+                            .el-input__inner {
+                                height: 40px;
+                                line-height: 40px;
+                                font-size: 14px;
+                                background-color: rgba(0, 0, 0, 0);
+                                border: 1px solid #15827C;
+                                box-shadow: 0 0 2px 1px #15827C inset;
+                                color: #FFFFFF;
+                            }
+                            .el-input-group__append, .el-input-group__prepend {
+                                height: 36px;
+                                font-size: 14px;
+                                cursor: pointer;
+                                background-color: rgba(0, 0, 0, 0);
+                                color: #FFFFFF;
+                                border: 1px solid #15827C;
+                                box-shadow: 0 0 2px 1px #15827C inset;
+                                p{
+                                    margin:0;
+                                    height:36px;
+                                    line-height:36px;
+                                }
+                            }
+                        }
+                    }
+                    .planAlarm-right-box {
+                        width: 718px;
+                        height: 599px;
+                        .planAlarm-text-box {
+                            width: 718px;
+                            height: 160px;
+                            display: flex;
+                            .planAlarm-text-left-box {
+                                width: 349px;
+                                height: 140px;
+                                margin-right: 10px;
+                                border-radius: 10px;
+                                background-color: #032C32;
+                                padding: 10px 15px;
+                                div {
+                                    display: flex;
+                                    p {
+                                        color: #fff;
+                                        line-height: 35px;
+                                        font-size: 16px;
+                                    }
+                                    p:nth-child(1) {
+                                    }
+                                    p:nth-child(2) {
+                                        flex: 1;
+                                    }
+                                }
+                            }
+                            .planAlarm-text-right-box {
+                                width: 349px;
+                                height: 140px;
+                                border-radius: 10px;
+                                background-color: #032C32;
+                                padding: 10px 15px;
+                                .box-one {
+                                    display: flex;
+                                    p {
+                                        color: #fff;
+                                        line-height: 35px;
+                                        font-size: 16px;
+                                    }
+                                    p:nth-child(1) {
+                                    }
+                                    p:nth-child(2) {
+                                        flex: 1;
+                                    }
+                                }
+                                .box-two {
+                                    display: flex;
+                                    .box-tile-p {
+                                        color: #fff;
+                                        line-height: 35px;
+                                        font-size: 16px;
+                                    }
+                                    .box-two-box {
+                                        flex: 1;
+                                        .box-two-box-min {
+                                            display: inline-block;
+                                            div {
+                                                display: flex;
+                                                overflow: hidden;
+                                                p:nth-child(1) {
+                                                    overflow: hidden;
+                                                    background-color: #11C01D;
+                                                    font-size: 18px;
+                                                    border-radius: 50%;
+                                                    width: 25px;
+                                                    height: 25px;
+                                                    color: #fff;
+                                                    line-height: 25px;
+                                                    text-align: center;
+                                                    margin: 5px 10px;
+                                                }
+                                                p:nth-child(2) {
+                                                    font-size: 16px;
+                                                    line-height: 35px;
+                                                    color: #fff;
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        .planAlarm-sensor-box {
+                            width: 698px;
+                            height: 178px;
+                            background-color: #032C32;
+                            border-radius: 10px;
+                            margin-top: 10px;
+                            padding: 15px 0 0 20px;
+                            div {
+                                display: inline-block;
+                                margin: 0 10px 10px 0;
+                                border-radius: 10px;
+                                width: 122px;
+                                height: 51px;
+                                background-color: #053539;
+                                padding: 13px 20px;
+                                .checkColor {
+                                    color: #FF0000;
+                                }
+                                p {
+                                    color: #fff;
+                                }
+                                p:nth-child(1) {
+                                    font-size: 18px;
+                                    line-height: 20px;
+                                    height: 20px;
+                                }
+                                p:nth-child(2) {
+                                    margin-top: 12px;
+                                    font-size: 14px;
+                                    line-height: 18px;
+                                    height: 18px;
+                                    display: block;
+                                    overflow: hidden;
+                                    text-overflow: ellipsis;
+                                    white-space: nowrap;
+                                }
+                            }
+                        }
+                        .planAlarm-img-box {
+                            width: 716px;
+                            height: 211px;
+                            background-color: #032C32;
+                            border-radius: 10px;
+                            margin-top: 10px;
+                            overflow: hidden;
+                            .img-title-p {
+                                font-size: 18px;
+                                height: 20px;
+                                line-height: 20px;
+                                margin: 15px 0 15px 30px;
+                                color: #fff;
+                            }
+                            .for-max-box {
+                                img {
+                                    cursor: pointer;
+                                    display: inline-block;
+                                    width: 212px;
+                                    height: 140px;
+                                    border-radius: 10px;
+                                    margin-left: 20px;
+                                }
+                            }
+                            .img-null-p {
+                                line-height: 150px;
+                                text-align: center;
+                                font-size: 20px;
+                                color: #999;
+                            }
+                        }
+                    }
+                    .lookImg {
+                        display: block;
+                        width: 971px;
+                        height: 546px;
+                        margin: 0 auto 0;
+                    }
+                }
+                .planAlarm-bottom-button-box {
+                    display: flex;
+                    .null-p {
+                        flex: 1;
+                    }
+                    .button-out-p {
+                        cursor: pointer;
+                        border: 1px solid #15827C;
+                        background-color: #000F14;
+                        color: #15827C;
+                        width: 100px;
+                        height: 30px;
+                        line-height: 30px;
+                        font-size: 14px;
+                        text-align: center;
+                        border-radius: 50px;
+                        margin-top: 15px;
+                    }
+                    .button-finish-p {
+                        cursor: pointer;
+                        border: 1px solid #15827C;
+                        background-color: #15827C;
+                        color: #fff;
+                        width: 100px;
+                        height: 30px;
+                        line-height: 30px;
+                        font-size: 14px;
+                        text-align: center;
+                        border-radius: 50px;
+                        margin-top: 15px;
+                        margin-left: 20px;
+                    }
+                }
+            }
+        }
+        .planAlarm-scrollbar {
+            overflow-y: scroll;
+            overflow-x: hidden;
+        }
+        .planAlarm-scrollbar::-webkit-scrollbar {
+            width: 6px; /*高宽分别对应横竖滚动条的尺寸*/
+            height: 6px;
+        }
+        .planAlarm-scrollbar::-webkit-scrollbar-thumb {
+            border-radius: 6px;
+            -webkit-box-shadow: inset 0 0 5px #15827C;
+            background: #15827C;
+        }
+        .planAlarm-scrollbar::-webkit-scrollbar-track {
+            -webkit-box-shadow: inset 0 0 6px rgba(3, 44, 50, 0);
+            border-radius: 0;
+            background: rgba(3, 44, 50, 0);
+        }
+    }
+</style>

+ 17 - 0
src/main.js

@@ -9,6 +9,7 @@ import 'element-ui/lib/theme-chalk/index.css';
 import '@/assets/styles/publicEle.scss'
 import Pagination from "@/components/Pagination/index.vue";
 import {judgmentNetworkReturnAddress,parseTime,goLogin } from '@/utils/public'
+import { accAdd,accSub,accDiv,accMul } from "@/utils/index";
 Vue.prototype.axios = axios
 Vue.prototype.$echarts = echarts;
 Vue.use(VueRouter);
@@ -18,6 +19,22 @@ Vue.config.productionTip = false
 Vue.prototype.parseTime = parseTime;
 Vue.prototype.judgmentNetworkReturnAddress = judgmentNetworkReturnAddress;
 Vue.prototype.goLogin = goLogin;
+Vue.prototype.accAdd = accAdd;
+Vue.prototype.accSub = accSub;
+Vue.prototype.accDiv = accDiv;
+Vue.prototype.accMul = accMul;
+
+Vue.prototype.msgSuccess = function (msg) {
+    this.$message({ showClose: true, message: msg, type: "success", offset:100 });
+}
+
+Vue.prototype.msgError = function (msg) {
+    this.$message({ showClose: true, message: msg, type: "error", offset:100 });
+}
+
+Vue.prototype.msgInfo = function (msg) {
+    this.$message.info(msg);
+}
 
 const router = new VueRouter({
   routes

+ 207 - 0
src/utils/index.js

@@ -0,0 +1,207 @@
+var countDecimals = function(num) {
+  var len = 0;
+  try {
+    num = Number(num);
+    var str = num.toString().toUpperCase();
+    if (str.split('E').length === 2) {
+      var isDecimal = false;
+      if (str.split('.').length === 2) {
+        str = str.split('.')[1];
+        if (parseInt(str.split('E')[0]) !== 0) {
+          isDecimal = true;
+        }
+      }
+      let x = str.split('E');
+      if (isDecimal) {
+        len = x[0].length;
+      }
+      len -= parseInt(x[1]);
+    } else if (str.split('.').length === 2) {
+      if (parseInt(str.split('.')[1]) !== 0) {
+        len = str.split('.')[1].length;
+      }
+    }
+  } catch (e) {
+    throw e;
+  } finally {
+    if (isNaN(len) || len < 0) {
+      len = 0;
+    }
+    return len;
+  }
+};
+var convertToInt = function(num) {
+  num = Number(num);
+  var newNum = num;
+  var times = countDecimals(num);
+  var temp_num = num.toString().toUpperCase();
+  if (temp_num.split('E').length === 2) {
+    newNum = Math.round(num * Math.pow(10, times));
+  } else {
+    newNum = Number(temp_num.replace(".", ""));
+  }
+  return newNum;
+};
+/**
+ * 参数处理
+ * @param {*} params  参数
+ */
+export function tansParams(params) {
+  let result = ''
+  for (const propName of Object.keys(params)) {
+    const value = params[propName];
+    var part = encodeURIComponent(propName) + "=";
+    if (value !== null && typeof (value) !== "undefined") {
+      if (typeof value === 'object') {
+        for (const key of Object.keys(value)) {
+          if (value[key] !== null && typeof (value[key]) !== 'undefined') {
+            let params = propName + '[' + key + ']';
+            var subPart = encodeURIComponent(params) + "=";
+            result += subPart + encodeURIComponent(value[key]) + "&";
+          }
+        }
+      } else {
+        result += part + encodeURIComponent(value) + "&";
+      }
+    }
+  }
+  return result
+}
+// 判断当前用户网络 外网/内网 返回接口地址
+export function judgmentNetworkReturnAddress() {
+  /*判断是否是内网IP*/
+  // 获取当前页面url
+  var curPageUrl = window.location.href;
+
+  var reg1 = /(http|ftp|https|www):\/\//g;//去掉前缀
+  curPageUrl =curPageUrl.replace(reg1,'');
+
+  var reg2 = /\:+/g;//替换冒号为一点
+  curPageUrl =curPageUrl.replace(reg2,'.');
+
+  curPageUrl = curPageUrl.split('.');//通过一点来划分数组
+
+
+  var ipAddress = curPageUrl[0]+'.'+curPageUrl[1]+'.'+curPageUrl[2]+'.'+curPageUrl[3];
+
+  var isInnerIp = false;//默认给定IP不是内网IP
+  var ipNum = getIpNum(ipAddress);
+  /**
+   * 私有IP:A类  10.0.0.0    -10.255.255.255
+   *       B类  172.16.0.0  -172.31.255.255
+   *       C类  192.168.0.0 -192.168.255.255
+   *       D类   127.0.0.0   -127.255.255.255(环回地址)
+   **/
+  var aBegin = getIpNum("10.0.0.0");
+  var aEnd = getIpNum("10.255.255.255");
+  var bBegin = getIpNum("172.16.0.0");
+  var bEnd = getIpNum("172.31.255.255");
+  var cBegin = getIpNum("192.168.0.0");
+  var cEnd = getIpNum("192.168.255.255");
+  var dBegin = getIpNum("127.0.0.0");
+  var dEnd = getIpNum("127.255.255.255");
+  isInnerIp = isInner(ipNum,aBegin,aEnd) || isInner(ipNum,bBegin,bEnd) || isInner(ipNum,cBegin,cEnd) || isInner(ipNum,dBegin,dEnd);
+  return isInnerIp?process.env.VUE_APP_BASE_LOCAL_API:process.env.VUE_APP_BASE_API;
+  /*获取IP数*/
+  function getIpNum(ipAddress) {
+    var ip = ipAddress.split(".");
+    var a = parseInt(ip[0]);
+    var b = parseInt(ip[1]);
+    var c = parseInt(ip[2]);
+    var d = parseInt(ip[3]);
+    var ipNum = a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d;
+    return ipNum;
+  }
+  function isInner(userIp,begin,end){
+    return (userIp>=begin) && (userIp<=end);
+  }
+}
+// 日期格式化
+export function parseTime(time, pattern) {
+  if (arguments.length === 0 || !time) {
+    return null
+  }
+  if(time.indexOf('T')!== -1){
+    let newTime = time.split('T')
+    time = newTime[0] + ' ' + newTime[1]
+  }
+  const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
+  let date
+  if (typeof time === 'object') {
+    date = time
+  } else {
+    if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
+      time = parseInt(time)
+    } else if (typeof time === 'string') {
+      time = time.replace(new RegExp(/-/gm), '/');
+    }
+    if ((typeof time === 'number') && (time.toString().length === 10)) {
+      time = time * 1000
+    }
+    date = new Date(time)
+  }
+  const formatObj = {
+    y: date.getFullYear(),
+    m: date.getMonth() + 1,
+    d: date.getDate(),
+    h: date.getHours(),
+    i: date.getMinutes(),
+    s: date.getSeconds(),
+    a: date.getDay()
+  }
+  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+    let value = formatObj[key]
+    // Note: getDay() returns 0 on Sunday
+    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
+    if (result.length > 0 && value < 10) {
+      value = '0' + value
+    }
+    return value || 0
+  })
+  return time_str
+}
+
+//加法
+export function accAdd(num1, num2) {
+  num1 = Number(num1);
+  num2 = Number(num2);
+  var dec1, dec2, times;
+  try { dec1 = countDecimals(num1) + 1; } catch (e) { dec1 = 0; }
+  try { dec2 = countDecimals(num2) + 1; } catch (e) { dec2 = 0; }
+  times = Math.pow(10, Math.max(dec1, dec2));
+  return (this.accMul(num1, times) + this.accMul(num2, times)) / times;
+}
+//减法
+export function accSub(num1, num2) {
+  num1 = Number(num1);
+  num2 = Number(num2);
+  var dec1, dec2, times;
+  try { dec1 = countDecimals(num1) + 1; } catch (e) { dec1 = 0; }
+  try { dec2 = countDecimals(num2) + 1; } catch (e) { dec2 = 0; }
+  times = Math.pow(10, Math.max(dec1, dec2));
+  return Number((this.accMul(num1, times) - this.accMul(num2, times)) / times);
+}
+//除法
+export function accDiv(num1, num2) {
+  num1 = Number(num1);
+  num2 = Number(num2);
+  var t1 = 0,
+    t2 = 0,
+    dec1, dec2;
+  try { t1 = countDecimals(num1); } catch (e) {}
+  try { t2 = countDecimals(num2); } catch (e) {}
+  dec1 = convertToInt(num1);
+  dec2 = convertToInt(num2);
+  return this.accMul((dec1 / dec2), Math.pow(10, t2 - t1));
+}
+//乘法
+export function accMul(num1, num2) {
+  num1 = Number(num1);
+  num2 = Number(num2);
+  var times = 0,
+    s1 = num1.toString(),
+    s2 = num2.toString();
+  try { times += countDecimals(s1); } catch (e) {}
+  try { times += countDecimals(s2); } catch (e) {}
+  return convertToInt(s1) * convertToInt(s2) / Math.pow(10, times);
+}

File diff suppressed because it is too large
+ 2223 - 2522
src/views/courtyardManage/courtyardHome.vue


+ 0 - 1
src/views/courtyardManage/labPersonDetail.vue

@@ -50,7 +50,6 @@
                 <el-table-column align="center" header-align='center' prop="subName" label="实验室" width="300px"></el-table-column>
                 <el-table-column align="center" header-align='center' prop="typeName" label="安全分类" width="300px"></el-table-column>
                 <el-table-column align="center" header-align='center' prop="levelName" label="安全分级" width="300px"></el-table-column>
-                <!--<el-table-column align="center" header-align='center' prop="userNames" label="实验室人数"></el-table-column>-->
                 <el-table-column align="center" header-align='center' prop="userNames" label="实验室人数">
                     <template  slot-scope="scope">
                         <el-tooltip v-for="(item,index) in scope.row.userInfoList" class="item" effect="dark" :content="'签到时间:'+item.createTime" placement="top">