wenningning 7 месяцев назад
Родитель
Сommit
a7788da731

+ 44 - 0
src/api/ncs_device_type.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+/**
+ * 设备类型相关接口
+ * @param params
+ * @returns {*|Promise|Promise<unknown>}
+ */
+export function getList(params) {
+  return request({
+    url: '/ncs/deviceType/getDeviceTypeChildrenVO',
+    method: 'POST',
+    loading: true,
+    data: params,
+    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
+  })
+}
+
+/** 新增设备类型 */
+export function add(params) {
+  return request({
+    url: '/ncs/deviceType',
+    method: 'POST',
+    loading: true,
+    data: params
+  })
+}
+
+/** 删除设备类型 */
+export function remove(id) {
+  return request({
+    url: `/ncs/deviceType/${id}`,
+    method: 'DELETE',
+    loading: true
+  })
+}
+
+/** 更新设备类型 */
+export function update(id, params) {
+  return request({
+    url: `/ncs/deviceType/${id}`,
+    method: 'put',
+    data: params
+  })
+}

+ 44 - 0
src/api/ncs_language.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+/**
+ * 多语言相关接口
+ * @param params
+ * @returns {*|Promise|Promise<unknown>}
+ */
+export function getByCode(params) {
+  return request({
+    url: 'ncs/language/getByCode',
+    method: 'POST',
+    loading: false,
+    data: params,
+    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
+  })
+}
+
+/** 新增多语言 */
+export function add(params) {
+  return request({
+    url: 'ncs/language',
+    method: 'POST',
+    loading: true,
+    data: params
+  })
+}
+
+/** 删除多语言 */
+export function remove(id) {
+  return request({
+    url: `ncs/language/${id}`,
+    method: 'DELETE',
+    loading: true
+  })
+}
+
+/** 更新多语言 */
+export function update(id, params) {
+  return request({
+    url: `ncs/language/${id}`,
+    method: 'put',
+    data: params
+  })
+}

+ 6 - 0
src/router/index.js

@@ -711,6 +711,12 @@ export const adminRoutes = [
         component: () => import('@/views/ncs-led/led-admin'),
         name: 'admin-led-device',
         meta: { title: i18n.t('tab.ledDeviceManager'), icon: 'led', noCache: true }
+      },
+      {
+        path: 'device_type',
+        component: () => import('@/views/ncs-orginazition/device-type.vue'),
+        name: 'admin-device-type',
+        meta: { title: i18n.t('deviceManage.deviceType'), icon: 'component', noCache: true }
       }
     ]
   },

+ 86 - 0
src/utils/enum/DeviceTypeNewEnum.js

@@ -0,0 +1,86 @@
+
+// 设备枚举,只有页面引用的才需要写在这里,不需要用的不用写,在后台配置即可
+export const DEVICE_TYPE_ENUM = {
+    NURSE_HOST: 'NURSE_HOST', // 护士主机
+    NURSE_WATCH: 'NURSE_WATCH', // 护士移动
+    DIGIT_BED_DEVICE: 'DIGIT_BED_DEVICE', // 床位分机
+    DOOR_DEVICE: 'DOOR_DEVICE', // 门口机
+    TRANSFER_DEVICE: 'TRANSFER_DEVICE', // 总线转换盒
+    RS485_TRANSFER: 'RS485_TRANSFER', // 485转换盒
+    SIMULATE_BED_DEVICE: 'SIMULATE_BED_DEVICE', // 模拟分机
+    RS485_DOOR: 'RS485_DOOR', // 485门口分机
+    SIMULATE_EMERGENCY_BUTTON: 'SIMULATE_EMERGENCY_BUTTON', // 模拟紧急按钮
+    SIMULATE_DOOR_LIGHT: 'SIMULATE_DOOR_LIGHT', // 模拟门灯
+    VITAL_SIGNS_DEVICE: 'VITAL_SIGNS_DEVICE', // 体征设备
+    LED_SCREEN: 'LED_SCREEN', // LED点阵屏
+    BREASTPLATE: 'BREASTPLATE', // 胸牌/手环
+    S433_TRANSFER_BOX: 'S433_TRANSFER_BOX', // 433无线转换盒
+    ALARM_BODY_INDUCTIVE: 'ALARM_BODY_INDUCTIVE', // 红外报警器
+    DOOR_LOCK: 'DOOR_LOCK', // 门磁传感器
+    ALARM_RESTRAINT_BAND: 'ALARM_RESTRAINT_BAND', // 约束带报警器
+    SMART_LIFE_GATEWAY: 'SMART_LIFE_GATEWAY', // 智慧生活网关
+    SMART_LIFE_VOICE_GATE: 'SMART_LIFE_VOICE_GATE', // 智慧生活语音网关
+    CURTAIN: 'CURTAIN', // 窗帘
+    SWITCH: 'SWITCH', // 开关
+    SIMULATE_BLUE_CODE: 'SIMULATE_BLUE_CODE', // 模拟BLUE CODE
+    EMERGENCY_BUTTON: 'EMERGENCY_BUTTON' // 紧急按钮
+}
+// export const DEVICE_TYPE = (
+//   {
+//     NURSE_HOST: [1, i18n.t('deviceType.NURSE_HOST')], // 护士主机
+//     DOCTOR_HOST: [2, i18n.t('deviceType.DOCTOR_HOST')], // 医生主机
+//     DOOR_DEVICE: [3, i18n.t('deviceType.DOOR_DEVICE')], // 门口机
+//     DIGIT_BED_DEVICE: [4, i18n.t('deviceType.DIGIT_BED_DEVICE')], // 床位分机
+//     LCD_SCREEN: [5, i18n.t('deviceType.LCD_SCREEN')], // LCD走廊屏
+//     LED_SCREEN: [6, i18n.t('deviceType.LED_SCREEN')], // LED点阵屏
+//     NURSE_WATCH: [7, i18n.t('deviceType.NURSE_WATCH')], // 护士移动
+//     WORKER_WATCH: [8, i18n.t('deviceType.WORKER_WATCH')], // 护工移动
+//     USER_WATCH: [9, i18n.t('deviceType.USER_WATCH')], // 用户移动
+//     CELL_PHONE: [10, i18n.t('deviceType.CELL_PHONE')], // 手机App
+//     TRANSFER_DEVICE: [11, i18n.t('deviceType.TRANSFER_DEVICE')], // 总线转换盒
+//     SIMULATE_BED_DEVICE: [12, i18n.t('deviceType.SIMULATE_BED_DEVICE')], // 模拟分机
+//     SIMULATE_EMERGENCY_BUTTON: [13, i18n.t('deviceType.SIMULATE_EMERGENCY_BUTTON')], // 模拟紧急按钮
+//     SIMULATE_DOOR_LIGHT: [14, i18n.t('deviceType.SIMULATE_DOOR_LIGHT')], // 模拟门灯
+//     REMOTE_CONTROL: [15, i18n.t('deviceType.REMOTE_CONTROL')], // 遥控器
+//     BEACON: [16, i18n.t('deviceType.BEACON')], // 信标
+//     INFORMATION_BOARD: [17, i18n.t('deviceType.INFORMATION_BOARD')], // 信息看版
+//     ENTRANCE_GUARD: [18, i18n.t('deviceType.ENTRANCE_GUARD')], // 门禁设备
+//     VISITATION: [19, i18n.t('deviceType.VISITATION')], // 探视机
+//     RS485_TRANSFER: [20, i18n.t('deviceType.RS485_TRANSFER')], // 485转换盒
+//     EMERGENCY_BUTTON: [21, i18n.t('deviceType.EMERGENCY_BUTTON')], // 紧急按钮
+//     RS485_DOOR: [22, i18n.t('deviceType.RS485_DOOR')], // 485门口分机
+//     ALARM_BODY_INDUCTIVE: [23, i18n.t('deviceType.ALARM_BODY_INDUCTIVE')], // 红外报警器
+//     ALARM_WATER_OVERFLOW: [24, i18n.t('deviceType.ALARM_WATER_OVERFLOW')], // 用水监控器
+//     ALARM_HOUSEHOLD_GAS: [25, i18n.t('deviceType.ALARM_HOUSEHOLD_GAS')], // 家用燃起报警器
+//     ALARM_HOUSEHOLD_SMOKE: [26, i18n.t('deviceType.ALARM_HOUSEHOLD_SMOKE')], // 家用烟雾报警器
+//     ALARM_BUTTON_SOS: [27, i18n.t('deviceType.ALARM_BUTTON_SOS')], // 一键报警器
+//     VITAL_SIGNS_DEVICE: [28, i18n.t('deviceType.VITAL_SIGNS_DEVICE')], // 体征设备
+//     ALARM_RESTRAINT_BAND: [29, i18n.t('deviceType.ALARM_RESTRAINT_BAND')], // 约束带报警器
+//     DOOR_LOCK: [30, i18n.t('deviceType.DOOR_LOCK')], // 门磁传感器
+//     EMERGENCY_GATEWAY: [31, i18n.t('deviceType.EMERGENCY_GATEWAY')], // 报警网关
+//     ALARM_433BUTTON: [32, i18n.t('deviceType.ALARM_433BUTTON')], // 433报警器
+//     OTHER_HOST: [33, i18n.t('deviceType.OTHER_HOST')], // 其他主机
+//     BREASTPLATE: [34, i18n.t('deviceType.BREASTPLATE')], // 胸牌/手环
+//     OWON_X5_GATEWAY: [35, i18n.t('deviceType.OWON_X5_GATEWAY')], // OWONX5网关
+//     FALL_DETECTION_RADAR: [36, i18n.t('deviceType.FALL_DETECTION_RADAR')], // 防跌倒雷达
+//     HUMAN_DETECTION_RADAR: [37, i18n.t('deviceType.HUMAN_DETECTION_RADAR')], // 睡眠监测雷达
+//     ALARM_INFUSION: [38, i18n.t('deviceType.ALARM_INFUSION')], // 输液报警器
+//     ELECTRONIC_FENCE: [39, i18n.t('deviceType.ELECTRONIC_FENCE')], // 电子围栏
+//     S433_DOOR_LAMP: [40, i18n.t('deviceType.S433_DOOR_LAMP')], // 433无线门灯
+//     S433_TRANSFER_BOX: [41, i18n.t('deviceType.S433_TRANSFER_BOX')], // 433无线转换盒
+//     S433_RECEIVER: [42, i18n.t('deviceType.S433_RECEIVER')], // 433接收器
+//     SLEEPMATTRESS: [43, i18n.t('deviceType.SLEEPMATTRESS')], // 睡眠床垫
+//     S4GINTERCOM: [44, i18n.t('deviceType.S4G_INTERCOM')], // 4G对讲器
+//     MULTIFUNCTIONAL_BUTTON: [45, i18n.t('deviceType.MULTIFUNCTIONAL_BUTTON')], // 多功能按钮
+//     WATCH_IW: [46, i18n.t('deviceType.WATCH_IW')], // 智能手表-埃微
+//     WATCH_BSJ: [55, i18n.t('deviceType.WATCH_BSJ')], // 智能手表-博实结
+//     S433_BJMD: [47, i18n.t('deviceType.S433_BJMD')], // 报警门灯
+//     SOS_VOICE_BUTTON: [48, i18n.t('deviceType.SOS_VOICE_BUTTON')], // SOS语音按钮
+//     PTT: [49, i18n.t('deviceType.PTT')], // 一键通
+//     SMART_LIFE_GATEWAY: [50, i18n.t('zy20240611.SMART_LIFE_GATEWAY')], // 智慧生活网关
+//     SMART_LIFE_VOICE_GATE: [51, i18n.t('zy20240611.SMART_LIFE_VOICE_GATE')], // 智慧生活语音网关
+//     CURTAIN: [52, i18n.t('zy20240611.CURTAIN')], // 窗帘
+//     SWITCH: [53, i18n.t('zy20240611.SWITCH')], // 开关
+//     SIMULATE_BLUE_CODE: [54, i18n.t('zy20240611.SIMULATE_BLUE_CODE')]
+//   }
+// )

+ 0 - 1
src/views/message-center/messages/index.vue

@@ -54,7 +54,6 @@ import {MESSAGE_OPEN_TYPE} from "@/utils/enum/MessageOpenTypeEnum";
 import {MESSAGE_STATUS} from "@/utils/enum/MessageStatusEnum";
 import * as API_Messages from '@/api/messages'
 import * as API_MessageType from '@/api/message_type'
-import {DEVICE_TYPE} from "@/utils/enum/DeviceTypeEnum";
 export default {
   name: "index",
   components: { ButtonCellRenderList, ButtonCellRender, ListFilter, RadioFilter },

Разница между файлами не показана из-за своего большого размера
+ 449 - 433
src/views/ncs-device/components/deviceManager.vue


Разница между файлами не показана из-за своего большого размера
+ 1554 - 0
src/views/ncs-device/components/deviceManager3.vue


+ 137 - 579
src/views/ncs-device/components/nbDeviceConditionView.vue

@@ -1,6 +1,7 @@
 <template>
     <div>
         <ag-grid-layout
+            v-if="show"
                 toolbar
                 :table-height="tableHeight"
                 theme="ag-theme-alpine"
@@ -28,15 +29,7 @@
     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 * as API_DEVICE_TYPE from '@/api/ncs_device_type'
     import ButtonCellRenderList from '@/components/AgGridCellRender/ButtonCellRenderList'
     const DeviceUrl = domain.DeviceUrl
     export default {
@@ -53,8 +46,6 @@
             return {
                 /** ag-grid参数 **/
                 pageData: {}, // 翻页数据
-                errorId: null,
-                shopVisible: false,
                 columnDefs: null,
                 rowData: [],
                 defaultColDef: {},
@@ -62,7 +53,6 @@
                 gridApi: {},
                 columnApi: {},
                 localeText: AG_GRID_LOCALE_CN,
-                filterState: null,
                 rowSelection: null,
                 frameworkComponents: null,
                 /** 列表参数 */
@@ -70,62 +60,17 @@
                     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"
+              deviceTypeList: [],
+              typeParams: {
+                lg: this.$i18n.locale
+              },
+              show: false
             }
         },
         computed: {
@@ -135,164 +80,138 @@
             }
         },
         beforeMount() {
+          this.API_GetDeviceTypeList()
             this.gridOptions = {}
-            this.columnDefs = [
+        },
+        mounted() {
+            window.onresize = this.windowResize
+            this.gridApi = this.gridOptions.api
+            this.gridColumnApi = this.gridOptions.columnApi
+            this.gridColumnApi.applyColumnState({
+                state: [
+                    {
+                        colId: 'id',
+                        sort: 'desc'
+                    }
+                ]
+            })
+            // this.initWebSocket()
+        },
+        methods: {
+          API_GetDeviceTypeList() {
+            const _this = this
+            let data = []
+            API_DEVICE_TYPE.getList(this.typeParams).then(res => {
+              res.forEach(item => {
+                if (item.bool_device) {
+                  item.key = item.title
+                  data.push(item)
+                }
+                item.children.forEach(t => {
+                  if (t.bool_device) {
+                    t.key = t.title
+                    data.push(t)
+                  }
+                })
+              })
+              _this.deviceTypeList = data
+              this.columnDefs = [
                 {
-                    headerName: '#',
-                    headerCheckboxSelection: true,
-                    headerCheckboxSelectionFilteredOnly: true,
-                    checkboxSelection: true,
-                    sortable: true, filter: false,
-                    width: 80,
-                    resizable: false,
-                    valueGetter: this.hashValueGetter
+                  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
+                  headerName: this.$t('deviceManage.deviceType'), field: 'device_type', sortable: true,
+                  filterFramework: 'ListFilter', width: 160,
+                  filterParams: {
+                    listData: this.deviceTypeList
+                  },
+                  valueGetter: this.deviceTypeGetter
                 },
                 // lockPosition 锁定位置,会在第一列
                 // lockPinned = true 不能拖动然后固定
                 // resizeable 单元个大小是否可以调整
                 {
-                    headerName: this.$t('deviceManage.ethMac'),
-                    field: 'eth_mac',
-                    sortable: true,
-                    filter: 'agTextColumnFilter'
+                  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.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.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.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',
+                  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
-                                }
-                            }
+                  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
+                      }
+                    }
+                  },
+                  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('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 = {
+              ]
+              this.defaultColDef = {
                 // filter: 'agTextColumnFilter',
                 sortable: true,
                 resizable: true,
@@ -300,29 +219,28 @@
                 filter: true,
                 // comparator: this.dateCustomComparator,
                 filterParams: {
-                    debounceMs: 500,
-                    newRowsAction: 'keep',
-                    textCustomComparator: this.textCustomComparator
+                  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: [
+              }
+              this.rowSelection = 'multiple'
+              this.show = true
+              setTimeout(() => {
+                window.onresize = this.windowResize
+                this.gridApi = this.gridOptions.api
+                this.gridColumnApi = this.gridOptions.columnApi
+                this.gridColumnApi.applyColumnState({
+                  state: [
                     {
-                        colId: 'id',
-                        sort: 'desc'
+                      colId: 'id',
+                      sort: 'desc'
                     }
-                ]
+                  ]
+                })
+              }, 200)
             })
-            // this.getShop(this.$store.getters.partId)
-            // this.initWebSocket()
-        },
-        methods: {
+          },
             windowResize() {
                 this.$set(this, 'mainAreaHeight', Number(document.documentElement.clientHeight) - 100)
             },
@@ -368,30 +286,7 @@
                         }
                     })
                 })
-                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)
-                    }
-                }
-            },
-
             /**
              * 过滤状态发生变化,发送到服务器检索数据
              */
@@ -443,9 +338,8 @@
             },
             /** 获取设备类型文字显示,从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)
+              const deviceType = this.deviceTypeList.find(type => type.value === params.data.device_type)
+              return deviceType.title;
             },
             /** 格式化时间函数 */
             unixDateFormatter(param) {
@@ -474,298 +368,16 @@
                     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) {
-                    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)
@@ -804,66 +416,12 @@
             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;
+              const deviceType = this.deviceTypeList.find(type => type.value === val)
+              return deviceType.bool_show_line
             }
         }
     }

+ 25 - 5
src/views/ncs-interaction/index.vue

@@ -123,7 +123,6 @@
 import * as API_interaction from '@/api/ncs_interaction'
 import { unixToDate } from '@/utils/Foundation'
 import { AG_GRID_LOCALE_CN } from '@/utils/AgGridVueLocaleCn'
-import {DEVICE_TYPE} from "@/utils/enum/DeviceTypeEnum";
 import {TCP_TYPE} from "@/utils/enum/TcpTypeEnum";
 import ButtonCellRender from "@/components/AgGridCellRender/ButtonCellRender";
 import RecordButtonCellRender from "@/components/AgGridCellRender/RecordButtonCellRender";
@@ -131,6 +130,7 @@ import RadioFilter from "@/components/AgGridCustomFilter/RadioFilter";
 import ListFilter from "@/components/AgGridCustomFilter/ListFilter";
 import * as API_Part from "@/api/ncs_partInfo";
 import * as API_ServiceInfo from "@/api/ncs_service_info";
+import * as API_DEVICE_TYPE from '@/api/ncs_device_type'
 const DeviceUrl = domain.DeviceUrl
 
 export default {
@@ -199,7 +199,8 @@ export default {
       dialogVisible: false,
       streaming2Show: false,
       streamingType: true,
-      recordDir: ''
+      recordDir: '',
+      deviceTypeList: []
     }
   },
   computed: {
@@ -208,6 +209,7 @@ export default {
     }
   },
   beforeMount() {
+    this.API_GetDeviceTypeList()
     this.gridOptions = {
       // onCellClicked: function (event) {
       //   console.log(event)
@@ -276,6 +278,23 @@ export default {
     // this.$refs.video2.addEventListener("pause", this.pause)
   },
   methods: {
+    API_GetDeviceTypeList() {
+      const _this = this
+      let data = []
+      API_DEVICE_TYPE.getList({ lg: this.$i18n.locale }).then(res => {
+        res.forEach(item => {
+          if (item.bool_device) {
+            data.push(item)
+          }
+          item.children.forEach(t => {
+            if (t.bool_device) {
+              data.push(t)
+            }
+          })
+        })
+        _this.deviceTypeList = data
+      })
+    },
     windowResize() {
       this.$set(this, 'mainAreaHeight', Number(document.documentElement.clientHeight) - 84)
     },
@@ -434,11 +453,12 @@ export default {
     formatterDeviceType(param) {
       if (param.data.outerior_action) {
         // return returnDeviceType(param.value)
-        return DEVICE_TYPE.getDescFromValue(param.value)
+        const deviceType = this.deviceTypeList.find(type => type.value === param.value)
+        return deviceType.title
       } else {
         if (param.value) {
-          // return returnDeviceType(param.value)
-          return DEVICE_TYPE.getDescFromValue(param.value)
+          const deviceType = this.deviceTypeList.find(type => type.value === param.value)
+          return deviceType.title
         } else {
           return this.$t('interaction.notOperated')
         }

+ 504 - 0
src/views/ncs-orginazition/device-type.vue

@@ -0,0 +1,504 @@
+<template>
+    <el-container  style="border: 1px solid #eee">
+      <el-container>
+        <el-header style="font-size: 12px; margin-top: 10px;">
+          <div style="text-align: left; float: left">
+              <el-input v-model="searchDeviceStr" :placeholder="$t('action.search')" clearable @change="clickSearch">
+                <el-select v-model="frameType" slot="prepend" :placeholder="$t('deviceManage.deviceLocationLevel')" @change="changeFrameType">
+                  <el-option :label="$t('action.all')" value="all"></el-option>
+                  <el-option :label="$t('frameManage.part')" value="3"></el-option>
+                  <el-option :label="$t('frameManage.room2')" value="4"></el-option>
+                  <el-option :label="$t('frameManage.bed2')" value="5"></el-option>
+                </el-select>
+<!--                <el-button slot="append" size="mini" icon="el-icon-search" @click="clickSearch"></el-button>-->
+              </el-input>
+          </div>
+          <div style="text-align: right">
+            <el-switch v-model="openType" :active-text="$t('deviceManage.collapse')" :inactive-text="$t('deviceManage.card')" style="margin-right: 20px;"></el-switch>
+            <el-button type="success" @click="handleAdd(null)" :loading="isSave">新增类型</el-button>
+          </div>
+        </el-header>
+        <el-main style="display: flex;">
+          <div style="width: 60%; height:850px; overflow-y: auto">
+            <el-collapse v-if="openType">
+              <el-collapse-item v-for="(item, index) in deviceTypeList" :key="index" style="margin-bottom: 10px;">
+                <div slot="title" style="width: 100%;min-height: 50px;" @click="checkType(item)">
+                  <div style="font-size: 15px;float: left;width: 20%;" :class="boolRoom ? 'mybg' : ''">{{ item.name }}
+                    <span v-if="item.bool_device" style="font-size: 12px;color: rgba(56,197,62)">(是设备)</span>
+                    <span v-else style="font-size: 12px;color: rgb(174,128,158,0.23)">(不是设备)</span>
+                  </div>
+                  <div :class="boolRoom ? 'mybg' : ''"  style="margin: 0;float: left;width: 60%;">
+                    <div style="float: left;height: 100%">
+                      <el-tag effect="plain" type="success">{{ item.code }}
+                        <span v-if="item.bool_device">({{item.value}})</span>
+                        <span v-else>({{item.children.length}}个设备)</span>
+                      </el-tag>
+                      <el-tag v-if="item.bool_device" v-for="(t, i) in item.frame_type.split(',')" :key="i" effect="plain" :type="getColor(i)">{{ formatFrame(t) }}</el-tag>
+                    </div>
+                  </div>
+                  <div>
+                    <el-button type="primary" icon="el-icon-edit" circle @click="handleEdit(item)"></el-button>
+                    <el-button type="warning" icon="el-icon-circle-plus-outline" circle @click="handleAdd(item)"></el-button>
+                    <el-button type="danger" icon="el-icon-delete" circle @click="handleDel(item)"></el-button>
+                  </div>
+                </div>
+                <div>
+                  <el-card v-for="(t, i) in item.children" :key="i" class="box-card" shadow="hover" :body-style="{ padding: '0px', margin: '0px' }">
+                    <div class="clearfix" :class="boolBed ? 'mybg' : ''" style="margin: 0;padding: 15px 0px 10px 0px;display: block;" @click="checkType(t)">
+                      <div style="font-size: 15px;float: left;width: 20%;" :class="boolRoom ? 'mybg' : ''">{{ t.name }}
+                        <span v-if="t.bool_device" style="font-size: 12px;color: rgba(56,197,62)">(是设备)</span>
+                        <span v-else style="font-size: 12px;color: rgb(174,128,158,0.23)">(不是设备)</span>
+                      </div>
+                      <div :class="boolRoom ? 'mybg' : ''"  style="margin: 0;float: left;width: 60%;">
+                        <div style="float: left;height: 100%">
+                          <el-tag effect="plain" type="success">{{ t.code }}({{t.value}})</el-tag>
+                          <el-tag v-if="t.bool_device" v-for="(tt, ii) in t.frame_type.split(',')" :key="ii" effect="plain" :type="getColor(ii)">{{ formatFrame(tt) }}</el-tag>
+                        </div>
+                      </div>
+                      <div>
+                        <el-button type="primary" icon="el-icon-edit" circle @click="handleEdit(t)"></el-button>
+                        <el-button type="danger" icon="el-icon-delete" circle @click="handleDel(t)"></el-button>
+                      </div>
+                    </div>
+                  </el-card>
+                </div>
+              </el-collapse-item>
+            </el-collapse>
+
+            <el-row v-if="!openType" v-for="(item, index) in deviceTypeList" :key="index">
+              <el-col :span="24">
+                <el-card class="box-card" shadow="hover">
+                  <!--              房间start-->
+                  <div slot="header" :class="boolRoom ? 'mybg' : ''" class="clearfix" style="width: 100%;min-height: 40px;" @click="checkType(item)">
+                    <!--                  <div style="font-size: 15px;float: left;width: 10%;margin-top: 5px;">{{ item.name }}</div>-->
+                    <div style="font-size: 15px;float: left;width: 20%;margin-top: 5px;">{{ item.name }}
+                      <span v-if="item.bool_device" style="font-size: 12px;color: rgba(56,197,62)">(是设备)</span>
+                      <span v-else style="font-size: 12px;color: rgb(174,128,158,0.23)">(不是设备)</span>
+                    </div>
+                    <div style="margin: 0;float: left;width: 60%;">
+                      <div style="float: left;height: 100%">
+                        <el-tag effect="plain" type="success">{{ item.code }}
+                          <span v-if="item.bool_device">({{item.value}})</span>
+                          <span v-else>({{item.children.length}}个设备)</span>
+                        </el-tag>
+                        <el-tag v-if="item.bool_device" v-for="(t, i) in item.frame_type.split(',')" :key="i" effect="plain" :type="getColor(i)">{{ formatFrame(t) }}</el-tag>
+                      </div>
+                    </div>
+                    <div>
+                      <el-button type="primary" icon="el-icon-edit" circle @click="handleEdit(item)"></el-button>
+                      <el-button type="warning" icon="el-icon-circle-plus-outline" circle @click="handleAdd(item)"></el-button>
+                      <el-button type="danger" icon="el-icon-delete" circle @click="handleDel(item)"></el-button>
+                    </div>
+                  </div>
+                  <!--              房间end-->
+                  <!--              床位start-->
+                  <div>
+                    <el-card v-for="(t, i) in item.children" :key="i" class="box-card" shadow="hover" :body-style="{ padding: '0px', margin: '0px' }">
+                      <div class="clearfix" :class="boolBed ? 'mybg' : ''" style="margin: 0;padding: 15px 0 10px 0;min-height: 40px;display: block;" @click="checkType(t)">
+                        <div style="font-size: 15px;float: left;width: 20%;" :class="boolRoom ? 'mybg' : ''">{{ t.name }}
+                          <span v-if="t.bool_device" style="font-size: 12px;color: rgba(56,197,62)">(是设备)</span>
+                          <span v-else style="font-size: 12px;color: rgb(174,128,158,0.23)">(不是设备)</span>
+                        </div>
+                        <div :class="boolRoom ? 'mybg' : ''"  style="margin: 0;float: left;width: 60%;">
+                          <div style="float: left;height: 100%">
+                            <el-tag effect="plain" type="success">{{ t.code }}({{t.value}})</el-tag>
+                            <el-tag v-if="t.bool_device" v-for="(tt, ii) in t.frame_type.split(',')" :key="ii" effect="plain" :type="getColor(ii)">{{ formatFrame(tt) }}</el-tag>
+                          </div>
+                        </div>
+                        <div>
+                          <el-button type="primary" icon="el-icon-edit" circle @click="handleEdit(t)"></el-button>
+                          <el-button type="danger" icon="el-icon-delete" circle @click="handleDel(t)"></el-button>
+                        </div>
+                      </div>
+                    </el-card>
+                  </div>
+                  <!--              床位end-->
+                </el-card>
+              </el-col>
+            </el-row>
+          </div>
+          <div style="width: 40%">
+            <el-row style="margin: 15px">
+              <el-col :span="8">当前选择:<el-tag type="success">{{ nowTypeModel.name }}</el-tag></el-col>
+              <el-col :span="4">
+                <el-button type="success" @click="handleAddLg" size="mini" :loading="isSave">新增语言</el-button>
+              </el-col>
+            </el-row>
+            <el-table :data="languageList" id="myTableId" stripe border ref="refTable" height="520">
+              <el-table-column type="index" width="55" label="序号"></el-table-column>
+              <el-table-column prop="language" min-width="100" label="语音" align="center" />
+              <el-table-column prop="title" min-width="100" label="翻译名" align="center" />
+              <el-table-column style="text-align: left;" label="操作" width="120" fixed="right">
+                <template slot-scope="scope">
+                  <el-button type="primary" icon="el-icon-edit" circle @click="handleEditLg(scope.row)"></el-button>
+                  <el-button type="danger" icon="el-icon-delete" circle @click="handleDelLg(scope.row.id)"></el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </el-main>
+      </el-container>
+      <!-- 设备编辑弹窗 -->
+      <el-dialog :title="deviceEditTitle" :visible.sync="modelShow"
+                 :width="this.$i18n.locale === 'zh' ? '50%' : '60%'">
+        <el-form ref="deviceEditForm" :rules="formRules"
+                 :label-width="this.$i18n.locale === 'zh' ? '120px' : '165px'" :model="formModel">
+          <el-form-item label="类型名称" prop="name">
+            <el-input v-model="formModel.name"></el-input>
+          </el-form-item>
+          <el-form-item label="是否设备" prop="bool_device">
+            <el-switch v-model="formModel.bool_device" active-text="是设备" inactive-text="不是设备"></el-switch>
+          </el-form-item>
+          <el-form-item label="唯一编码" prop="code">
+            <el-input v-model="formModel.code"></el-input>
+          </el-form-item>
+          <el-form-item v-if="formModel.bool_device" label="开关" prop="bool_mac">
+            <el-switch v-model="formModel.bool_mac" active-text="必填Mac" inactive-text="不用填"></el-switch>
+            <el-switch v-model="formModel.bool_debug" style="margin-left: 20px" active-text="可调试重启" inactive-text="不可"></el-switch>
+            <el-switch v-model="formModel.bool_show_line" style="margin-left: 20px" active-text="显示在线" inactive-text="不显示"></el-switch>
+          </el-form-item>
+          <el-form-item v-if="formModel.bool_device" label="类型值" prop="value">
+            <el-input-number v-model="formModel.value" :min="1"></el-input-number>
+          </el-form-item>
+          <el-form-item v-if="formModel.bool_device" label="所在空间" prop="frame_type">
+            <el-checkbox-group v-model="formModel.frame_type">
+              <el-checkbox label="3" value="3">科室</el-checkbox>
+              <el-checkbox label="4" value="4">房间</el-checkbox>
+              <el-checkbox label="5" value="5">床位</el-checkbox>
+            </el-checkbox-group>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" @click="onSubmit">立即创建</el-button>
+            <el-button @click="modelShow = false" :disabled="disabled">取消</el-button>
+          </el-form-item>
+        </el-form>
+      </el-dialog>
+      <!-- 设备编辑弹窗 -->
+
+      <!-- 设备编辑弹窗 -->
+      <el-dialog :title="deviceEditTitle" :visible.sync="languageModelShow"
+                 :width="this.$i18n.locale === 'zh' ? '50%' : '60%'">
+        <el-form ref="deviceEditForm2" :rules="formRules2"
+                 :label-width="this.$i18n.locale === 'zh' ? '120px' : '165px'" :model="formModel">
+          <el-form-item v-if="!formModel.id" label="语音" prop="language">
+            <el-select v-model="formModel.language" placeholder="请选择语言">
+              <el-option v-for="(item, index) in language" :key="index" :label="item.label" :value="item.value"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="翻译名" prop="title">
+            <el-input v-model="formModel.title"></el-input>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" @click="onSubmit2">立即创建</el-button>
+            <el-button @click="languageModelShow = false" :disabled="disabled">取消</el-button>
+          </el-form-item>
+        </el-form>
+      </el-dialog>
+      <!-- 设备编辑弹窗 -->
+    </el-container>
+
+</template>
+
+<script>
+import draggable from 'vuedraggable'
+import * as API_DEVICE_TYPE from '@/api/ncs_device_type'
+import * as API_LANGUAGE from '@/api/ncs_language'
+
+export default {
+  name: 'device-frame',
+  components: { draggable },
+  data() {
+    return {
+      deviceList: [],
+      deviceTypeList: {},
+      tagColors: ['warning', 'danger', 'success', 'info'],
+      openType: true,
+      frameType: 'all',
+      boolPart: false,
+      boolRoom: false,
+      boolBed: false,
+      needUpdateList: [],
+      searchDeviceStr: '',
+      isSave: false,
+      originalDevices: [],
+      formModel: {
+        bool_device: true,
+        frame_type: [],
+        code: '',
+        value: null,
+        name: ''
+      },
+      params: {},
+      modelShow: false,
+      deviceEditTitle: '新增设备类型',
+      formRules: {
+        name: [
+          this.MixinRequired('请输入名称')
+        ],
+        code: [
+          this.MixinRequired('请输入唯一编码')
+        ],
+        value: [
+          this.MixinRequired('请输入类型值')
+        ],
+        frame_type: [
+          this.MixinRequired('请选择所在空间')
+        ]
+      },
+      formRules2: {
+        language: [
+          this.MixinRequired('请选择语言')
+        ],
+        title: [
+          this.MixinRequired('请输入翻译名')
+        ]
+      },
+      disabled: false,
+      languageList: [],
+      nowTypeModel: {
+        id: null,
+        name: '无'
+      },
+      languageModelShow: false,
+      language: [
+        {
+          value: 'en',
+          label: 'English'
+        },
+        {
+          value: 'zh',
+          label: '中文简体'
+        },
+        {
+          value: 'es',
+          label: 'Español'
+        },
+        {
+          value: 'ru',
+          label: 'Русский'
+        }
+      ]
+    }
+  },
+  mounted() {
+    this.API_GetDeviceTypeList()
+  },
+  methods: {
+    API_GetDeviceTypeList() {
+      const _this = this
+      API_DEVICE_TYPE.getList(this.params).then(res => {
+        _this.deviceTypeList = res
+        if (res) {
+          this.checkType(res[0])
+        }
+      })
+    },
+    API_GetLanguageList() {
+      const _this = this
+      API_LANGUAGE.getByCode({ code: this.nowTypeModel.code }).then(res => {
+        _this.languageList = res
+      })
+    },
+    clickSearch() {
+      if (this.searchDeviceStr) {
+        this.params.name = this.searchDeviceStr
+        // this.params.code = this.searchDeviceStr
+      } else {
+        // delete this.params.code
+        delete this.params.name
+      }
+      this.API_GetDeviceTypeList()
+    },
+    changeFrameType() {
+      if (this.frameType === 'all') {
+        delete this.params.frame_type
+      } else {
+        this.$set(this.params, 'frame_type', this.frameType)
+      }
+      this.API_GetDeviceTypeList()
+    },
+    getColor(index) {
+      return this.tagColors[index % this.tagColors.length]
+    },
+    handleAdd(item) {
+      this.formModel = {
+        bool_device: true,
+        bool_mac: true,
+        bool_debug: false,
+        bool_show_line: true,
+        frame_type: [],
+        code: '',
+        value: null,
+        name: ''
+      }
+      if (item) {
+        this.formModel.parent_id = item.id
+        this.deviceEditTitle = '新增《' + item.name +'》下级设备类型'
+      } else {
+        this.deviceEditTitle = '新增设备类型'
+      }
+      this.disabled = false
+      this.modelShow = true
+    },
+    handleEdit(item) {
+      this.formModel = this.MixinClone(item)
+      if (item.bool_device) {
+        this.formModel.frame_type = item.frame_type.split(',')
+      }
+      this.deviceEditTitle = '修改《' + item.name +'》设备类型'
+      this.disabled = false
+      this.modelShow = true
+    },
+    formatFrame(val) {
+      switch (val) {
+        case '3':
+          return '科室'
+        case '4':
+          return '房间'
+        case '5':
+          return '床位'
+        default:
+          return '未知'
+      }
+    },
+    checkType(item) {
+      if (item.id === this.nowTypeModel.id) {
+        return
+      }
+      this.nowTypeModel = item
+      this.API_GetLanguageList()
+    },
+    handleAddLg() {
+      this.deviceEditTitle = '新增《' + this.nowTypeModel.name +'》多语言'
+      this.formModel = {
+        code: this.nowTypeModel.code,
+        title: '',
+        language: null
+      }
+      this.disabled = false
+      this.languageModelShow = true
+    },
+    handleEditLg(item) {
+      this.formModel = this.MixinClone(item)
+      this.deviceEditTitle = '修改《' + this.nowTypeModel.name +'》多语言'
+      this.disabled = false
+      this.languageModelShow = true
+    },
+    onSubmit() {
+      this.$refs['deviceEditForm'].validate((valid) => {
+        if (valid) {
+          this.disabled = true
+          let params = this.MixinClone(this.formModel)
+          if (params.bool_device) {
+            params.frame_type.sort((a, b) => a - b)
+            params.frame_type = params.frame_type.join(',')
+          } else {
+            params.frame_type = null
+            params.value = null
+          }
+          if (params.id) {
+            API_DEVICE_TYPE.update(params.id, params).then(res => {
+              this.disabled = false
+              if (res.success) {
+                this.$message.success(this.$t('action.editSuccess') + '')
+                this.modelShow = false
+                this.API_GetDeviceTypeList()
+              } else {
+                this.$message.error(res.message)
+              }
+            })
+          } else {
+            API_DEVICE_TYPE.add(params).then(res => {
+              this.disabled = false
+              if (res.success) {
+                this.$message.success(this.$t('action.editSuccess') + '')
+                this.modelShow = false
+                this.API_GetDeviceTypeList()
+              } else {
+                this.$message.error(res.message)
+              }
+            })
+          }
+        }
+      })
+    },
+    onSubmit2() {
+      this.$refs['deviceEditForm2'].validate((valid) => {
+        if (valid) {
+          this.disabled = true
+          let params = this.MixinClone(this.formModel)
+          if (params.id) {
+            API_LANGUAGE.update(params.id, params).then(res => {
+              this.disabled = false
+              if (res.success) {
+                this.$message.success(this.$t('action.editSuccess') + '')
+                this.languageModelShow = false
+                this.API_GetLanguageList()
+              } else {
+                this.$message.error(res.message)
+              }
+            })
+          } else {
+            API_LANGUAGE.add(params).then(res => {
+              this.disabled = false
+              if (res.success) {
+                this.$message.success(this.$t('action.editSuccess') + '')
+                this.languageModelShow = false
+                this.API_GetLanguageList()
+              } else {
+                this.$message.error(res.message)
+              }
+            })
+          }
+        }
+      })
+    },
+    handleDel(item) {
+      if (item.children) {
+        this.$message.error('需要先删除子级设备类型')
+        return
+      }
+      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_TYPE.remove(item.id).then(res => {
+          this.$message.success(this.$t('action.editSuccess') + '')
+          this.API_GetDeviceTypeList()
+        })
+      })
+    },
+    handleDelLg(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_LANGUAGE.remove(id).then(res => {
+          this.$message.success(this.$t('action.editSuccess') + '')
+          this.API_GetLanguageList()
+        })
+      })
+    }
+  }
+}
+</script>
+
+<style scoped>
+.mybg {
+  background-color: rgba(70, 72, 73, 0.39)
+}
+.selected-list2 :hover{
+  cursor: pointer;
+}
+.el-input .el-select  {
+  width: 75px;
+}
+.el-input .el-button {
+  width: 40px;
+}
+.input-with-select .el-input-group__prepend {
+  background-color: #fff;
+}
+</style>