Browse Source

添加NB设备离线设备,低电量设备查询

wuyunfeng 2 years ago
parent
commit
05a0374192

+ 6 - 1
languages/en.js

@@ -1027,7 +1027,12 @@ module.exports = {
     entraceguardUser: 'Passage setting',
     customBoardManage: 'Custom Board Screen',
     customBoardDesigner: 'Designer Board Screen',
-    staffManageFrames: 'Staff Serve Structure'
+    staffManageFrames: 'Staff Serve Structure',
+    nbiotDeviceStatus:'Faulty IoT equipment',
+    offlineDevice:'off-line equipment',
+    lowBatteryDevice:'Low battery devices',
+    checkNetwork:'Check the network of the device',
+    changeBattery:'Replace the battery of the device'
   },
   deviceType: {
     NURSE_HOST: 'Nurse Host',

+ 6 - 2
languages/es.js

@@ -1029,8 +1029,12 @@ module.exports = {
     entraceguardUser: 'Configuración de paso',
     customBoardManage: 'Pantalla de tablero personalizada',
     customBoardDesigner: 'Pantalla del tablero de diseño',
-    staffManageFrames: 'Estructura del servicio al personal'
-
+    staffManageFrames: 'Estructura del servicio al personal',
+    nbiotDeviceStatus:'Equipo de Unión de objetos defectuosos',
+    offlineDevice:'Dispositivos fuera de línea',
+    lowBatteryDevice:'Equipos de baja potencia',
+    checkNetwork:'Comprobar la red del dispositivo',
+    changeBattery:'Reemplazar la batería del dispositivo'
   },
   deviceType: {
     NURSE_HOST: 'Enfermera anfitriona',

+ 6 - 1
languages/ru-RU.js

@@ -992,7 +992,12 @@ module.exports = {
     ledDevice: 'Светодиодные устройства',
     entraceguardUser: 'Параметры прохода',
     customBoardManage: 'Настройка экрана панели',
-    customBoardDesigner: 'Экран панели'
+    customBoardDesigner: 'Экран панели',
+    nbiotDeviceStatus:'неисправное оборудование МСУ',
+    offlineDevice:'Автономное оборудование',
+    lowBatteryDevice:'Низкоэлектрическое оборудование',
+    checkNetwork:'Проверить сеть устройства',
+    changeBattery:'Замена батарей в оборудовании'
   },
   deviceType: {
     NURSE_HOST: 'Устройство медсестры',

+ 10 - 2
languages/zh-CN.js

@@ -5,6 +5,7 @@ module.exports = {
     add: '新增',
     edit: '编辑',
     more: '更多',
+    view:'查看',
     delete: '删除',
     login: '登录',
     usernameMsg: 'Username',
@@ -419,7 +420,8 @@ module.exports = {
     card: '卡片显示',
     devices: '台设备',
     roomNoDevice: '房间没有设备',
-    bedNoDevice: '床位没有设备'
+    bedNoDevice: '床位没有设备',
+    operationAdvice:'操作建议'
   },
   clerkManage: {
     clerkEdit: '编辑成员信息',
@@ -1030,7 +1032,13 @@ module.exports = {
     entraceguardUser: '用户通行设置',
     customBoardManage: '信息看板设计',
     customBoardDesigner: '看板屏设计',
-    staffManageFrames: '空间管理设置'
+    staffManageFrames: '空间管理设置',
+    nbiotDeviceStatus:'故障物联设备',
+    offlineDevice:'离线设备',
+    lowBatteryDevice:'低电量设备',
+    checkNetwork:'检查设备网络',
+    changeBattery:'更换设备电池'
+
   },
   deviceType: {
     NURSE_HOST: '护士主机',

+ 26 - 0
src/api/ncs_nbdevicecondition.js

@@ -0,0 +1,26 @@
+import request from "@/utils/request";
+
+
+export function getList(params,partId,viewtype) {
+    return request({
+        url: viewtype===0?`/mgr/nbdevcie/getoffline/${partId}/page`:`/mgr/nbdevcie/getlowbattery/${partId}/page`,
+        method: 'POST',
+        loading: true,
+        data: params,
+        headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
+    })
+}
+
+export function getLowBatteryDevices(partid) {
+    return request({
+        url: `/mgr/nbdevcie/getlowbattery/${partid}`,
+        method: 'get'
+    })
+}
+
+export function getOfflineDevices(partid) {
+    return request({
+        url: `/mgr/nbdevcie/getoffline/${partid}`,
+        method: 'get'
+    })
+}

File diff suppressed because it is too large
+ 1 - 0
src/icons/svg/iot.svg


+ 8 - 0
src/router/index.js

@@ -149,6 +149,13 @@ export const partRoutes = [
         hidden: true
       },
       {
+        path: 'nbdevice-condition',
+        component: () => import('@/views/ncs-device/nbDeviceCondition'),
+        name: 'NbdeviceCondition',
+        meta: { title: i18n.t('tab.nbiotDeviceStatus'), icon: 'iot', noCache: true },
+        hidden: uiVersion === 2
+      },
+      {
         path: 'information-board',
         component: () => import('@/views/calling-board/index'),
         name: 'CallingBoard',
@@ -162,6 +169,7 @@ export const partRoutes = [
         meta: { title: i18n.t('tab.customBoardManage'), icon: 'designer', noCache: true },
         hidden: uiVersion === 2
       }
+
     ]
   },
   // {

+ 7 - 1
src/utils/mixin.js

@@ -65,8 +65,14 @@ export default {
       return hours + ':' + minutes + ':' + seconds
     }
   },
+  mounted(){
+    window.onresize = this.windowResize
+  },
   methods: {
-
+    windowResize() {
+      console.log('clientHeight',document.documentElement.clientHeight)
+        this.$set(this, 'mainAreaHeight', Number(document.documentElement.clientHeight) - 84)
+    },
 
     /** 返回克隆后的对象 */
     MixinClone(obj) {

+ 2 - 0
src/views/ncs-clerk/components/clerkList.vue

@@ -456,6 +456,8 @@ export default {
           listData: this.roleTransfer
         } },
       { headerName: this.$t('member.leaderName'), field: 'leader_name', sortable: true, filter: true, width: 180 },
+
+      { headerName: this.$t('member.passNo'), field: 'pass_no', sortable: true, filter: true, width: 180 },
       { headerName: this.$t('action.handle'), field: 'id',
         cellRendererFramework: 'ButtonCellRender',
         cellRendererParams: param => {

+ 877 - 0
src/views/ncs-device/components/nbDeviceConditionView.vue

@@ -0,0 +1,877 @@
+<template>
+    <div>
+        <ag-grid-layout
+                toolbar
+                :table-height="tableHeight"
+                theme="ag-theme-alpine"
+                :column-defs="columnDefs"
+                :row-data="rowData"
+                :locale-text="localeText"
+                :grid-options="gridOptions"
+                :debounce-vertical-scrollbar="true"
+                :default-col-def="defaultColDef"
+                :animate-rows="true"
+                :row-selection="rowSelection"
+                :framework-components="frameworkComponents"
+                @filterChanged="filterModifed"
+                @sortChanged="gridSortChange"
+        >
+        </ag-grid-layout>
+
+    </div>
+</template>
+
+<script>
+    import {AG_GRID_LOCALE_CN} from '@/utils/AgGridVueLocaleCn'
+    import {unix2Date} from '@/utils/Foundation'
+    import ButtonCellRender from '@/components/AgGridCellRender/ButtonCellRender'
+    import ListFilter from '@/components/AgGridCustomFilter/ListFilter'
+    import RadioFilter from '@/components/AgGridCustomFilter/RadioFilter'
+    import * as API_NbDeviceConditon from '@/api/ncs_nbdevicecondition'
+    import * as API_Frame from '@/api/ncs_hospitalFrame'
+    import * as API_SosDeviceSetting from '@/api/ncs_sos_device_settings'
+    import * as clerk_API from '@/api/ncs_clerk'
+    import {FRAME_TYPE} from '@/utils/enum/FrameTypeEnum'
+    import {DEVICE_TYPE} from '@/utils/enum/DeviceTypeEnum'
+    import {SOS_DEVICE_SETTING_TYPE} from "@/utils/enum/SosDeviceSettingTypeEnum";
+    import {VITAL_SIGNS_DEVICE_TYPE} from "@/utils/enum/VitalSignsDeviceEnum";
+    import * as shop_API from "@/api/ncs_shop";
+
+    import ButtonCellRenderList from '@/components/AgGridCellRender/ButtonCellRenderList'
+    const DeviceUrl = domain.DeviceUrl
+    export default {
+        name: "nbDeviceConditionView",
+        components: {ButtonCellRender, ListFilter, RadioFilter,
+            ButtonCellRenderList},
+        props:{
+            viewType:{  //0 离线设备 1 低电量设备
+                type:Number,
+                default:0
+            }
+        },
+        data() {
+            return {
+                /** ag-grid参数 **/
+                pageData: {}, // 翻页数据
+                errorId: null,
+                shopVisible: false,
+                columnDefs: null,
+                rowData: [],
+                defaultColDef: {},
+                gridOptions: {},
+                gridApi: {},
+                columnApi: {},
+                localeText: AG_GRID_LOCALE_CN,
+                filterState: null,
+                rowSelection: null,
+                frameworkComponents: null,
+                /** 列表参数 */
+                params: {
+                    page_size: 20,
+                    page_no: 1
+                },
+                /** device 弹窗 **/
+                deviceDialogVisible: false,
+                deviceEditTitle: this.$t('deviceManage.deviceAdd'),
+                deviceModel: {},
+                deviceTypeDisabled: false,
+
+                partFrames: [],
+                typeFrames: [],
+                /** 设备类型转换数组 **/
+                deviceTypeTransfer:  DEVICE_TYPE.getKeyValueList(),
+                deviceStatusTransfer: [
+                    {key: this.$t('deviceManage.statusTure'), value: 1, color: 'green'},
+                    {key: this.$t('deviceManage.statusFalse'), value: 0, color: 'red'}
+                ],
+                rolesOptions: [],
+                hasRoleId: false,
+                audioOptions: [],
+                rs485Options: [],
+                hasAudioId: false,
+                isVitalSigns: false,
+                hasSosDeviceSettings: false,
+                sosDeviceSetting: {},
+                sosDeviceSettingsTypeOptions: [
+                    {
+                        value: 0,
+                        label: '不开启'
+                    }, {
+                        value: 1,
+                        label: '防控模式'
+                    }, {
+                        value: 2,
+                        label: '关爱模式'
+                    }
+                ],
+                sosDeviceSettingEnum: SOS_DEVICE_SETTING_TYPE.getValueList(),
+                vitalSignsDeviceEnum: VITAL_SIGNS_DEVICE_TYPE.getValueList(),
+                isLedDevice: false,
+                websock: null,
+                onlineDevice: [],
+                // 请求当前科室的数据
+                shop: {},
+                serverAddress: {
+                    server_ip: '172.28.100.100',
+                    server_port: '8006'
+                },
+                serverAddressDialogVisible: false,
+                serverAddressRules: {
+                    serverIp: [
+                        this.MixinRequired(this.$t('deviceManage.inputServerIp'))
+                    ],
+                    serverPort: [
+                        this.MixinRequired(this.$t('deviceManage.inputServerPort'))
+                    ]
+                },
+                startTime: "06:00",
+                endTime: "18:00"
+            }
+        },
+        computed: {
+            tableHeight() {
+                console.log('mainAreaHeight',this.mainAreaHeight)
+                return  this.mainAreaHeight -100
+            }
+        },
+        beforeMount() {
+            this.gridOptions = {}
+            this.columnDefs = [
+                {
+                    headerName: '#',
+                    headerCheckboxSelection: true,
+                    headerCheckboxSelectionFilteredOnly: true,
+                    checkboxSelection: true,
+                    sortable: true, filter: false,
+                    width: 80,
+                    resizable: false,
+                    valueGetter: this.hashValueGetter
+                },
+                {headerName: 'ID', field: 'id', sortable: true, filter: 'agNumberColumnFilter', width: 100},
+                {
+                    headerName: this.$t('deviceManage.deviceType'), field: 'device_type', sortable: true,
+                    filterFramework: 'ListFilter', width: 160,
+                    filterParams: {
+                        listData: this.deviceTypeTransfer
+                    },
+                    valueGetter: this.deviceTypeGetter
+                },
+                // lockPosition 锁定位置,会在第一列
+                // lockPinned = true 不能拖动然后固定
+                // resizeable 单元个大小是否可以调整
+                {
+                    headerName: this.$t('deviceManage.ethMac'),
+                    field: 'eth_mac',
+                    sortable: true,
+                    filter: 'agTextColumnFilter'
+                },
+                {
+                    headerName: this.$t('deviceManage.frameFullName'),
+                    field: 'full_name',
+                    sortable: true,
+                    flex: 1,
+                    filter: 'agTextColumnFilter'
+                },
+                {
+                    headerName: this.$t('deviceManage.deviceName'),
+                    field: 'name',
+                    sortable: true,
+                    filter: 'agTextColumnFilter'
+                },
+                {
+                    headerName: this.$t('deviceManage.status'), field: 'status', width: 120, sortable: true,
+                    filterFramework: 'RadioFilter',
+                    filterParams: {
+                        listData: this.deviceStatusTransfer
+                    },
+                    cellRenderer: this.deviceStatusFormatter
+                },
+                {
+                    headerName: this.$t('deviceManage.connect'),
+                    field: 'online_state',
+                    sortable: false,
+                    width: 120,
+                    filter: 'agTextColumnFilter',
+
+                    filterParams: {
+                        textCustomComparator: (filter, value, filterText) => {
+                            if (filterText) {
+                                const filterTextLowerCase = filterText.toLowerCase()
+                                const valueLowerCase = value.toString().toLowerCase()
+                                switch (filter) {
+                                    case 'contains':
+                                        return valueLowerCase.indexOf(filterTextLowerCase) >= 0
+                                    case 'notContains':
+                                        return valueLowerCase.indexOf(filterTextLowerCase) === -1
+                                    case 'equals':
+                                        return valueLowerCase === filterTextLowerCase
+                                    case 'notEqual':
+                                        return valueLowerCase !== filterTextLowerCase
+                                    case 'startsWith':
+                                        return valueLowerCase.indexOf(filterTextLowerCase) === 0
+                                    case 'endsWith':
+                                        var index = valueLowerCase.lastIndexOf(filterTextLowerCase)
+                                        return index >= 0 && index === (valueLowerCase.length - filterTextLowerCase.length)
+                                    default:
+                                        // should never happen
+                                        console.warn('invalid filter type ' + filter)
+                                        return false
+                                }
+                            }
+                        }
+                    },
+                    cellRenderer: this.onlineStateFormatter
+                },
+
+                {
+                    headerName: this.$t('deviceManage.operationAdvice'), field: '', width:230, sortable: true,
+                    filterFramework: 'RadioFilter',
+                    filterParams: {
+                        listData: this.deviceStatusTransfer
+                    },
+                    cellRenderer: ()=>{return "<span style='color:red;'>"+(this.viewType===0?this.$t('tab.checkNetwork'):this.$t('tab.changeBattery'))+"</span>"}
+                },
+
+
+
+
+
+                // {
+                //     headerName: this.$t('action.edit'), field: 'id',
+                //     cellRendererFramework: 'ButtonCellRender',
+                //     cellRendererParams: {
+                //         onClick: this.handleEdit,
+                //         label: this.$t('action.edit'),
+                //         buttonType: 'primary',
+                //         buttonSize: 'mini'
+                //     },
+                //     filter: false,
+                //     pinned: 'right',
+                //     lockPinned: true,
+                //     width: 80,
+                //     resizable: false,
+                //     sortable: false
+                // },
+                // {
+                //     headerName: this.$t('action.delete'), field: 'id',
+                //     cellRendererFramework: 'ButtonCellRender',
+                //     cellRendererParams: param => {
+                //         return {
+                //             onClick: this.deleteSingle,
+                //             label: this.$t('action.delete'),
+                //             buttonType: 'danger',
+                //             buttonSize: 'mini',
+                //             disabled: param.data['member_name'] === 'superadmin'
+                //         }
+                //     },
+                //     pinned: 'right',
+                //     lockPinned: true,
+                //     width: 80,
+                //     resizable: false,
+                //     filter: false,
+                //     sortable: false
+                // },
+                //
+                // {
+                //     headerName: this.$t('action.debug'), field: 'id',
+                //     cellRendererFramework: 'ButtonCellRender',
+                //     cellRendererParams: param => {
+                //         return {
+                //             onClick: this.deleteSingle,
+                //             label: this.$t('action.debug'),
+                //             buttonType: 'danger',
+                //             buttonSize: 'mini',
+                //             disabled: param.data['member_name'] === 'superadmin'
+                //         }
+                //     },
+                //     pinned: 'right',
+                //     lockPinned: true,
+                //     width: 80,
+                //     resizable: false,
+                //     filter: false,
+                //     sortable: false
+                // }
+            ]
+            this.defaultColDef = {
+                // filter: 'agTextColumnFilter',
+                sortable: true,
+                resizable: true,
+                enableValue: true,
+                filter: true,
+                // comparator: this.dateCustomComparator,
+                filterParams: {
+                    debounceMs: 500,
+                    newRowsAction: 'keep',
+                    textCustomComparator: this.textCustomComparator
+                }
+            }
+            this.rowSelection = 'multiple'
+        },
+        mounted() {
+            window.onresize = this.windowResize
+            this.gridApi = this.gridOptions.api
+            this.gridColumnApi = this.gridOptions.columnApi
+            this.gridColumnApi.applyColumnState({
+                state: [
+                    {
+                        colId: 'id',
+                        sort: 'desc'
+                    }
+                ]
+            })
+            // this.getShop(this.$store.getters.partId)
+            // this.initWebSocket()
+        },
+        methods: {
+            windowResize() {
+                this.$set(this, 'mainAreaHeight', Number(document.documentElement.clientHeight) - 100)
+            },
+            /** 加载列表数据 */
+            getList() {
+                const param = this.MixinClone(this.params)
+                this.gridApi.showLoadingOverlay()
+                API_NbDeviceConditon.getList(param,this.$store.getters.partId,this.viewType).then(response => {
+                    const deviceData = [...response.data]
+                    deviceData.forEach(item => {
+                        if (this.onlineDevice.length > 0) {
+                            if (this.isCannotBeOnline(item.device_type)) {
+                                if (item.eth_mac) {
+                                    const mac = this.onlineDevice.filter(p => p != null && (p.toLowerCase() === item.eth_mac.toLowerCase()))[0]
+                                    // console.log('在线设备1', mac)
+                                    if (mac !== undefined && mac !== null) {
+                                        item['online_state'] = this.$t('deviceManage.connectTrue')
+                                    } else {
+                                        item['online_state'] = this.$t('deviceManage.connectFalse')
+                                    }
+                                }
+                            } else {
+                                item['online_state'] = '/'
+                            }
+                        } else {
+                            if (this.isCannotBeOnline(item.device_type)) {
+                                item['online_state'] = this.$t('deviceManage.connectFalse')
+                            } else {
+                                item['online_state'] = '/'
+                            }
+                        }
+                    })
+                    this.rowData = deviceData
+                    this.pageData = {
+                        page_no: response.page_no,
+                        page_size: response.page_size,
+                        data_total: response.data_total
+                    }
+                    this.$nextTick(() => {
+                        const node = this.gridApi.getDisplayedRowAtIndex(0)
+                        if (node !== null && node !== undefined) {
+                            node.setSelected(true)
+                        }
+                    })
+                })
+                this.typeFrames = this.partFrames
+            },
+            getTypeFrame(partId) {
+                if (this.shop.shop_type === "0" && this.shop.parent_id === -1) {
+                    API_Frame.getAllFrames(partId).then(res => {
+                        this.partFrames = [...res]
+                    })
+                } else {
+                    API_Frame.getFramesPartId(partId).then(res => {
+                        this.partFrames = [...res]
+                    })
+                }
+            },
+            /** 将partFrames做分割 */
+            getFramesByType(frame_type) {
+                if (this.partFrames != null) {
+                    if (frame_type === FRAME_TYPE.HOSPITAL || frame_type === FRAME_TYPE.PART) {
+                        this.typeFrames = this.partFrames.filter(item => item.type === FRAME_TYPE.HOSPITAL || item.type === FRAME_TYPE.PART)
+                    } else {
+                        this.typeFrames = this.partFrames.filter(item => item.type === frame_type)
+                    }
+                }
+            },
+
+            /**
+             * 过滤状态发生变化,发送到服务器检索数据
+             */
+            filterModifed(param) {
+                var model = param.api.getFilterModel()
+                // 连接状态不经过服务器过滤
+                delete model.online_state
+                this.params.filter = JSON.stringify(model)
+                this.getList()
+            },
+            gridSortChange(param) {
+                const columnState = param.columnApi.getColumnState()
+                // 排序状态
+                const sortState = columnState.filter(function (s) {
+                    console.log('s',s)
+                    return s.sort != null
+                }).map(function (s) {
+                    return {
+                        colId: s.colId,
+                        sort: s.sort,
+                        sortIndex: s.sortIndex
+                    }
+                }).sort(function (a, b) {
+                    return a.sortIndex - b.sortIndex
+                })
+                if (sortState.length > 0) {
+                    if (sortState.length === 1) {
+                        this.params.sort = sortState[0].colId
+                        this.params.dir = sortState[0].sort
+                    } else {
+                        let sortstring = ''
+                        sortState.forEach(function (item) {
+                            sortstring += item.colId + ' ' + item.sort + ','
+                        })
+                        this.params.sort = sortstring.substring(0, sortstring.length - 1)
+                        this.params.dir = ' '
+                    }
+                } else {
+                    delete this.params.sort
+                    delete this.params.dir
+                }
+
+                this.getList()
+            },
+            /** 处理搜索 */
+            handlerSearch(keywords) {
+                this.params.query = keywords
+                this.getList()
+            },
+            /** 获取设备类型文字显示,从deviceTypeTransfer 中找出value值对应的key显示出来 */
+            deviceTypeGetter(params) {
+                const gridVal = params.data.device_type
+                // return this.deviceTypeTransfer.filter(p => p.value === gridVal).map(p => p.key)
+                return DEVICE_TYPE.getDescFromValue(gridVal)
+            },
+            /** 格式化时间函数 */
+            unixDateFormatter(param) {
+                if (!param.value) return ''
+                return unix2Date(param.value * 1000)
+            },
+            /** 设备状态格式化 **/
+            deviceStatusFormatter(params) {
+                if (params.value === null || params.value === undefined) return ''
+                const item = this.deviceStatusTransfer.filter(p => p.value === params.value)[0]
+                if (item) {
+                    return '<span style="color:' + item.color + ';">' + item.key + '</span>'
+                } else {
+                    return ''
+                }
+            },
+            /** 设备连接状态格式化 **/
+            onlineStateFormatter(params) {
+                if (params.value === this.$t('deviceManage.connectTrue')) {
+                    // return '<span style="color:green;">在线</span>'
+                    return '<span style="color:green;">' + this.$t('deviceManage.connectTrue') + '</span>'
+                } else if (params.value === this.$t('deviceManage.connectFalse')) {
+                    // return '<span style="color:gray;">离线</span>'
+                    return '<span style="color:gray;">' + this.$t('deviceManage.connectFalse') + '</span>'
+                } else {
+                    return '<span style="color:gray;"> / </span>'
+                }
+            },
+            /** 删除设备 **/
+            deleteSingle(row) {
+                this.handlerDelete(row.id)
+            },
+            /** 删除设备 **/
+            handlerDelete(id) {
+                this.$confirm(this.$t('action.sureDelete'), this.$t('action.waring'), {
+                    confirmButtonText: this.$t('action.yes'),
+                    cancelButtonText: this.$t('action.cancel'),
+                    type: 'warning'
+                }).then(() => {
+                    API_Device.remove(id).then(
+                        response => {
+                            this.getList()
+                        }
+                    ).catch(response => {
+                        this.$message({
+                            type: 'info',
+                            message: response.message
+                        })
+                    })
+                    if (this.hasSosDeviceSettings) {
+                        API_SosDeviceSetting.deleteByDeviceId(id).then(() => {
+                            this.hasSosDeviceSettings = false
+                            this.getList()
+                        })
+                    }
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: this.$t('action.cancelDelete')
+                    })
+                })
+            },
+            /** 设备类型选中变化  **/
+            deviceTypeChange(val) {
+                this.deviceTypeChangeToFrameTypeChange(val)
+                this.deviceModel.name = DEVICE_TYPE.getDescFromValue(val)
+                if (val === DEVICE_TYPE.SIMULATE_BED_DEVICE || // 只能直接在后面加设备,会判断错误,必须重新用val = 设备
+                    val === DEVICE_TYPE.RS485_DOOR ||
+                    val === DEVICE_TYPE.SIMULATE_EMERGENCY_BUTTON ||
+                    val === DEVICE_TYPE.SIMULATE_DOOR_LIGHT ||
+                    val === DEVICE_TYPE.EMERGENCY_BUTTON) { // 模拟设备不需要mac地址
+                    this.deviceRules.eth_mac[0].required = false
+                    this.deviceRules.eth_mac[1].pattern = null
+                } else if (val === DEVICE_TYPE.REMOTE_CONTROL) {
+                    this.deviceRules.eth_mac[1].pattern = null
+                    this.deviceRules.eth_mac[0].required = true
+                } else if (val === DEVICE_TYPE.DIGIT_BED_DEVICE) {
+                    this.deviceRules.eth_mac[1].pattern = null
+                    this.deviceRules.eth_mac[0].required = true
+                } else {
+                    // this.deviceRules.eth_mac[1].pattern = /^([0-9A-Fa-f]{2}:?){6}/gi
+                    this.deviceRules.eth_mac[1].pattern = null
+                    this.deviceRules.eth_mac[0].required = true
+                }
+                this.hasRoleId = val === DEVICE_TYPE.NURSE_WATCH
+                this.hasAudioId = val === DEVICE_TYPE.SIMULATE_BED_DEVICE ||
+                    val === DEVICE_TYPE.RS485_DOOR ||
+                    val === DEVICE_TYPE.SIMULATE_EMERGENCY_BUTTON ||
+                    val === DEVICE_TYPE.SIMULATE_DOOR_LIGHT
+                this.isVitalSigns = val === DEVICE_TYPE.VITAL_SIGNS_DEVICE
+                this.hasSosDeviceSettings = val === DEVICE_TYPE.ALARM_BODY_INDUCTIVE ||
+                    val === DEVICE_TYPE.DOOR_LOCK ||
+                    val === DEVICE_TYPE.ALARM_RESTRAINT_BAND || val === DEVICE_TYPE.BREASTPLATE
+                this.isLedDevice = val === DEVICE_TYPE.LED_SCREEN
+            },
+            /** 设备类型选中对应的空间结构  **/
+            deviceTypeChangeToFrameTypeChange(val) {
+                if (val === DEVICE_TYPE.NURSE_HOST ||
+                    val === DEVICE_TYPE.OTHER_HOST ||
+                    val === DEVICE_TYPE.DOCTOR_HOST ||
+                    val === DEVICE_TYPE.LED_SCREEN ||
+                    val === DEVICE_TYPE.LCD_SCREEN ||
+                    val === DEVICE_TYPE.NURSE_WATCH ||
+                    val === DEVICE_TYPE.WORKER_WATCH ||
+                    val === DEVICE_TYPE.TRANSFER_DEVICE ||
+                    val === DEVICE_TYPE.INFORMATION_BOARD ||
+                    val === DEVICE_TYPE.RS485_TRANSFER) {
+                    this.getFramesByType(FRAME_TYPE.PART)
+                } else if (val === DEVICE_TYPE.DOOR_DEVICE ||
+                    val === DEVICE_TYPE.SIMULATE_EMERGENCY_BUTTON ||
+                    val === DEVICE_TYPE.RS485_DOOR ||
+                    val === DEVICE_TYPE.SIMULATE_DOOR_LIGHT ||
+                    val === DEVICE_TYPE.BEACON) {
+                    this.getFramesByType(FRAME_TYPE.ROOM)
+                } else if (val === DEVICE_TYPE.DIGIT_BED_DEVICE ||
+                    val === DEVICE_TYPE.SIMULATE_BED_DEVICE ||
+                    val === DEVICE_TYPE.REMOTE_CONTROL ||
+                    val === DEVICE_TYPE.CELL_PHONE ||
+                    val === DEVICE_TYPE.ALARM_433BUTTON ||
+                    val === DEVICE_TYPE.ALARM_INFUSION
+                ) {
+                    this.getFramesByType(FRAME_TYPE.BED)
+                } else {
+                    this.getTypeFrame(this.$store.getters.partId)
+                    this.typeFrames = this.partFrames
+                }
+            },
+            androidDevice(param){
+                const val =param.data.device_type
+                return val === DEVICE_TYPE.NURSE_HOST ||
+                    val === DEVICE_TYPE.OTHER_HOST ||
+                    val === DEVICE_TYPE.NURSE_HOST ||
+                    val === DEVICE_TYPE.DOCTOR_HOST ||
+                    val === DEVICE_TYPE.TRANSFER_DEVICE ||
+                    val === DEVICE_TYPE.DOOR_DEVICE ||
+                    val === DEVICE_TYPE.DIGIT_BED_DEVICE
+
+            },
+            s485Device(param){
+                const val =param.data.device_type
+                return val === DEVICE_TYPE.RS485_DOOR ||
+                    val === DEVICE_TYPE.SIMULATE_BED_DEVICE && param.data.trans_rs485_id!==null
+            },
+            /** 添加设备事件 **/
+            handleAdd() {
+                this.deviceModel = {
+                    soft_ver: 'SV1.0',
+                    hard_ver: 'HV1.0',
+                    priority: 1,
+                    code: 'C' + parseInt(Math.random() * 100000),
+                    model: 'M' + parseInt(Math.random() * 100000),
+                    status: 1,
+                    name: ''
+                }
+                this.sosDeviceSetting = {
+                    type: 0,
+                    unit: '小时',
+                    setting_time: 120
+                }
+                if (Object.keys(this.frame).length > 0) {
+                    this.$set(this.deviceModel, 'frame_id', this.frame.id)
+                }
+                delete this.deviceModel.id
+                this.hasRoleId = false
+                this.getRoles({
+                    page_size: 200,
+                    page_no: 1,
+                    fixedCondition: ' shop_id = -1',
+                    sort: ' role_id',
+                    dir: 'desc'
+                })
+                this.hasAudioId = false
+                this.isVitalSigns = false
+                this.hasSosDeviceSettings = false
+                this.isLedDevice = false
+                this.getDevices(this.$store.getters.partId)
+                this.deviceEditTitle = this.$t('deviceManage.deviceAdd')
+                this.deviceDialogVisible = true
+                this.deviceTypeDisabled = false // 新增设备可以选择设备类型
+                this.typeFrames = this.partFrames
+            },
+            /** 修改设备  **/
+            handleEdit(params) {
+                this.getRoles({
+                    page_size: 200,
+                    page_no: 1,
+                    fixedCondition: ' shop_id = -1',
+                    sort: ' role_id',
+                    dir: 'desc'
+                })
+                this.getDevices(params.part_id)
+                this.deviceTypeChangeToFrameTypeChange(params.device_type)
+                this.hasRoleId = params.device_type === DEVICE_TYPE.NURSE_WATCH
+                this.hasAudioId = params.device_type === DEVICE_TYPE.SIMULATE_BED_DEVICE ||
+                    params.device_type === DEVICE_TYPE.RS485_DOOR ||
+                    params.device_type === DEVICE_TYPE.SIMULATE_EMERGENCY_BUTTON ||
+                    params.device_type === DEVICE_TYPE.SIMULATE_DOOR_LIGHT
+                this.isVitalSigns = params.device_type === DEVICE_TYPE.VITAL_SIGNS_DEVICE
+
+                if (params.device_type === DEVICE_TYPE.ALARM_BODY_INDUCTIVE ||
+                    params.device_type === DEVICE_TYPE.DOOR_LOCK ||
+                    params.device_type === DEVICE_TYPE.ALARM_RESTRAINT_BAND || params.device_type === DEVICE_TYPE.BREASTPLATE) {
+                    this.hasSosDeviceSettings = true
+                    this.getSosDeviceSetting(params.id)
+                } else {
+                    this.hasSosDeviceSettings = false
+                }
+
+                this.isLedDevice = params.device_type === DEVICE_TYPE.LED_SCREEN
+                this.deviceModel = {
+                    ...params
+                }
+                this.deviceEditTitle = this.$t('deviceManage.deviceEdit')
+                this.deviceDialogVisible = true
+                this.deviceTypeDisabled = true // 修改设备时,不能改变设备类型
+            },
+            /** 新增 提交表单 */
+            handlerFormSubmit(formName) {
+                this.$refs[formName].validate((valid) => {
+                    if (valid) {
+                        const _this = this;
+                        console.log('this.deviceModel', this.deviceModel)
+                        /** 新增 */
+                        if (!this.deviceModel.id) {
+                            if (this.frame.type != null) {
+                                this.deviceModel.part_id = this.frame.type === FRAME_TYPE.HOSPITAL ? this.frame.hospital_id : this.frame.part_id
+                            } else {
+                                this.deviceModel.part_id = this.$store.getters.partId
+                            }
+                            API_Device.add(this.deviceModel).then(r => {
+                                this.$message.success(this.$t('action.saveSuccess'))
+                                _this.device = r
+                                this.sosDeviceSetting.device_id = _this.device.id
+                                this.sosDeviceSetting.part_id = _this.device.part_id
+                                // 是报警设备
+                                if (this.hasSosDeviceSettings) {
+                                    // 是胸牌/手表
+                                    if (this.deviceModel.device_type === DEVICE_TYPE.BREASTPLATE) {
+                                        this.sosDeviceSetting.cron_str = this.startTime + ',' + this.endTime
+                                    }
+                                    this.sosDeviceSetting.device_type = this.deviceModel.device_type
+                                    this.sosDeviceSetting.device_eth_mac = this.deviceModel.eth_mac
+                                    API_SosDeviceSetting.add(this.sosDeviceSetting).then(() => {
+                                        this.$message.success(this.$t('action.saveSuccess'))
+                                        this.hasSosDeviceSettings = false
+                                    })
+                                }
+                                this.deviceDialogVisible = false
+                                this.getList()
+                            })
+                        } else {
+                            /** 修改 */
+                            API_Device.update(this.deviceModel.id, this.deviceModel).then(() => {
+                                this.$message.success(this.$t('action.editSuccess'))
+
+                                if (this.hasSosDeviceSettings) {
+                                    this.sosDeviceSetting.device_id = this.deviceModel.id
+                                    this.sosDeviceSetting.part_id = this.deviceModel.part_id
+                                    this.sosDeviceSetting.device_type = this.deviceModel.device_type
+                                    // 是胸牌/手表
+                                    if (this.deviceModel.device_type === DEVICE_TYPE.BREASTPLATE) {
+                                        this.sosDeviceSetting.cron_str = this.startTime + ',' + this.endTime
+                                    }
+                                    API_SosDeviceSetting.updateById(this.sosDeviceSetting.id, this.sosDeviceSetting).then(() => {
+                                        this.$message.success(this.$t('action.saveSuccess'))
+                                        this.hasSosDeviceSettings = false
+                                    })
+                                }
+
+                                this.deviceDialogVisible = false
+                                this.getList()
+                            })
+                        }
+                    }
+                })
+            },
+            /** 分页大小发生改变 */
+            handlePageSizeChange(size) {
+                this.params.page_size = size
+                this.getList()
+            },
+
+            /** 分页页数发生改变 */
+            handlePageCurrentChange(page) {
+                this.params.page_no = page
+                this.getList()
+            },
+            getRoles(param) {
+                // 获取角色
+                clerk_API.getRoles(param).then(response => {
+                    this.rolesOptions = response.data
+                })
+            },
+            getDevices(partId) {
+                // 获取设备列表
+                API_Device.getDeviceByType(partId, DEVICE_TYPE.TRANSFER_DEVICE).then(response => {
+                    this.audioOptions = response
+                })
+                API_Device.getDeviceByType(partId, DEVICE_TYPE.RS485_TRANSFER).then(response => {
+                    this.rs485Options = response
+                })
+            },
+            getSosDeviceSetting(deviceId) {
+                API_SosDeviceSetting.getSosDeviceSetting(deviceId).then(r => {
+                    this.sosDeviceSetting = r;
+                    if (r.cron_str) {
+                        let str = r.cron_str.split(',')
+                        if (str.length === 2) {
+                            this.startTime = str[0]
+                            this.endTime = str[1]
+                        }
+                    }
+                })
+            },
+            getShop(shopId) {
+                shop_API.getShop(shopId).then(res => {
+                    this.shop = res;
+                    this.getTypeFrame(shopId)
+                })
+            },
+
+            initWebSocket: function () {
+                var stockbase = DeviceUrl.replace('http', 'ws')
+                this.websock = new WebSocket(stockbase + '/deviceonline/' + this.$store.getters.uuid)
+                this.websock.onopen = this.websocketonopen
+                this.websock.onerror = this.websocketonerror
+                this.websock.onmessage = this.websocketonmessage
+                this.websock.onclose = this.websocketclose
+            },
+            websocketonopen: function () {
+                console.log(this.$t('deviceManage.webSocketSuccess'))
+            },
+            websocketonerror: function (e) {
+                console.log(this.$t('deviceManage.webSocketError'))
+            },
+            websocketonmessage: function (e) {
+                this.onlineDevice = JSON.parse(e.data)
+                if (this.rowData !== null) {
+                    for (let i = 0; i < this.rowData.length; i++) {
+                        if (this.isCannotBeOnline(this.rowData[i].device_type)) {
+                            if (this.rowData[i].eth_mac) {
+                                const mac = this.onlineDevice.filter(p => p.toLowerCase() === this.rowData[i].eth_mac.toLowerCase())[0]
+                                this.rowData[i]['online_state'] = (mac !== undefined && mac !== null) ? this.$t('deviceManage.connectTrue') : this.$t('deviceManage.connectFalse')
+                            }
+                        } else {
+                            this.rowData[i]['online_state'] = '/'
+                        }
+                    }
+                    //只刷新在线状态列数据
+                    var params = {
+                        columns: ['online_state']
+                    }
+                    this.gridApi.refreshCells(params);
+
+                }
+            },
+            websocketclose: function (e) {
+                console.log('connection closed (' + e.code + ')')
+            },
+            batchDelete() {
+                const rows = this.gridApi.getSelectedRows()
+                if (rows.length === 0) {
+                    this.$message({type: 'info', message: this.$t('action.pleaseChoiceDelete')})
+                    return
+                }
+                const ids = []
+                rows.forEach(function (item) {
+                    ids.push(item.id)
+                })
+                this.handlerDelete(ids.join(','))
+            },
+            deviceServerChange() {
+                this.serverAddressDialogVisible = true
+            },
+            updateDevicesServerIp() {
+                API_Device.updateDevicesServerIp(this.serverAddress).then(r => {
+                    this.$message.success(this.$t('action.settingsSuccess'))
+                    this.serverAddressDialogVisible = false
+                })
+            },
+
+            openDebug(param){
+                API_Device.openDebug(param.id).then(res=>{
+                    this.$message.success(this.$t('action.handleSuccess'))
+                }).catch(err=>{
+                    this.$message.error(this.$t('action.handleFailed'))
+                })
+            },
+            rebootDevice(params){
+                API_Device.rebootDevice(params.id).then(res=>{
+                    this.$message.success(this.$t('action.handleSuccess'))
+                }).catch(err=>{
+                    this.$message.error(this.$t('action.handleFailed'))
+                })
+            },
+            /**
+             * 判断设备是否为模拟分机这种,无法在线是设备
+             */
+            isCannotBeOnline(val) {
+                return val === DEVICE_TYPE.NURSE_HOST ||
+                    val === DEVICE_TYPE.OTHER_HOST ||
+                    val === DEVICE_TYPE.NURSE_HOST ||
+                    val === DEVICE_TYPE.DOCTOR_HOST ||
+                    val === DEVICE_TYPE.NURSE_WATCH ||
+                    val === DEVICE_TYPE.WORKER_WATCH ||
+                    val === DEVICE_TYPE.TRANSFER_DEVICE ||
+                    val === DEVICE_TYPE.DOOR_DEVICE ||
+                    val === DEVICE_TYPE.DIGIT_BED_DEVICE ||
+                    val === DEVICE_TYPE.CELL_PHONE ||
+                    val === DEVICE_TYPE.ENTRANCE_GUARD ||
+                    val === DEVICE_TYPE.OWON_X5_GATEWAY ||
+                    val === DEVICE_TYPE.HUMAN_DETECTION_RADAR ||
+                    val === DEVICE_TYPE.INFORMATION_BOARD ||
+                    val === DEVICE_TYPE.ALARM_433BUTTON ||
+                    val === DEVICE_TYPE.ALARM_BODY_INDUCTIVE||
+                    val === DEVICE_TYPE.S433_TRANSFER_BOX;
+            },
+            getDeviceType() {
+                return DEVICE_TYPE;
+            }
+        }
+    }
+</script>
+
+<style scoped>
+    /deep/ .toolbar{
+    height: 0;
+}
+</style>

+ 68 - 0
src/views/ncs-device/nbDeviceCondition.vue

@@ -0,0 +1,68 @@
+<template>
+<el-main >
+    <el-tabs type="border-card" tab-position="top">
+        <el-tab-pane >
+            <span slot="label">
+                <el-badge :value="offline" :hidden="offline===0"   class="item">{{this.$t("tab.offlineDevice")}}</el-badge>
+            </span>
+           <nb-device-condition-view :view-type="0"></nb-device-condition-view>
+        </el-tab-pane>
+        <el-tab-pane l>
+            <span slot="label">
+                <el-badge  :value="lowbattery" :hidden="lowbattery===0"  class="item">{{this.$t("tab.lowBatteryDevice")}}</el-badge>
+            </span>
+            <nb-device-condition-view :view-type="1"></nb-device-condition-view></el-tab-pane>
+
+    </el-tabs>
+</el-main>
+</template>
+
+<script>
+    import * as API_NbDeviceConditon from '@/api/ncs_nbdevicecondition'
+    import NbDeviceConditionView from "./components/nbDeviceConditionView";
+    export default {
+        name: "nbDeviceCondition",
+        components: {NbDeviceConditionView},
+        computed: {
+            asideHeight() {
+                return this.mainAreaHeight-20
+            }
+        },
+        data() {
+            return {
+                offline:0,
+                lowbattery:0
+            }
+        },
+
+        mounted() {
+            window.onresize = this.windowResize
+            this.getBadge()
+        },
+        methods:{
+            windowResize() {
+                this.$set(this, 'mainAreaHeight', Number(document.documentElement.clientHeight) - 84)
+            },
+
+            getBadge() {
+                API_NbDeviceConditon.getOfflineDevices(this.$store.getters.partId).then(response => {
+                    this.offline=[...response].length
+                })
+                API_NbDeviceConditon.getLowBatteryDevices(this.$store.getters.partId).then(response => {
+                    this.lowbattery=[...response].length
+                })
+            },
+        }
+
+    }
+</script>
+
+<style scoped>
+/deep/ .el-badge__content.is-fixed{
+    top:5px
+}
+.el-main{
+    margin: 8px;
+    padding: 0;
+}
+</style>