diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/views/systemConfig/alarmLevel/components/editCh4Level.vue b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue new file mode 100644 index 0000000..717c30b --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/views/systemConfig/alarmLevel/components/editCh4Level.vue b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue new file mode 100644 index 0000000..717c30b --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editDigLevel.vue b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue new file mode 100644 index 0000000..84271be --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/views/systemConfig/alarmLevel/components/editCh4Level.vue b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue new file mode 100644 index 0000000..717c30b --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editDigLevel.vue b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue new file mode 100644 index 0000000..84271be --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editGasLevel.vue b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue new file mode 100644 index 0000000..b890225 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/views/systemConfig/alarmLevel/components/editCh4Level.vue b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue new file mode 100644 index 0000000..717c30b --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editDigLevel.vue b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue new file mode 100644 index 0000000..84271be --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editGasLevel.vue b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue new file mode 100644 index 0000000..b890225 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue new file mode 100644 index 0000000..812966e --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/views/systemConfig/alarmLevel/components/editCh4Level.vue b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue new file mode 100644 index 0000000..717c30b --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editDigLevel.vue b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue new file mode 100644 index 0000000..84271be --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editGasLevel.vue b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue new file mode 100644 index 0000000..b890225 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue new file mode 100644 index 0000000..812966e --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue new file mode 100644 index 0000000..4449430 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue @@ -0,0 +1,299 @@ + + + + + + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/views/systemConfig/alarmLevel/components/editCh4Level.vue b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue new file mode 100644 index 0000000..717c30b --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editDigLevel.vue b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue new file mode 100644 index 0000000..84271be --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editGasLevel.vue b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue new file mode 100644 index 0000000..b890225 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue new file mode 100644 index 0000000..812966e --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue new file mode 100644 index 0000000..4449430 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue @@ -0,0 +1,299 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue new file mode 100644 index 0000000..ddd9433 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue @@ -0,0 +1,238 @@ + + + + + + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/views/systemConfig/alarmLevel/components/editCh4Level.vue b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue new file mode 100644 index 0000000..717c30b --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editDigLevel.vue b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue new file mode 100644 index 0000000..84271be --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editGasLevel.vue b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue new file mode 100644 index 0000000..b890225 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue new file mode 100644 index 0000000..812966e --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue new file mode 100644 index 0000000..4449430 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue @@ -0,0 +1,299 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue new file mode 100644 index 0000000..ddd9433 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue @@ -0,0 +1,238 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editO2Level.vue b/src/views/systemConfig/alarmLevel/components/editO2Level.vue new file mode 100644 index 0000000..6879ec5 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editO2Level.vue @@ -0,0 +1,312 @@ + + + + + + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/views/systemConfig/alarmLevel/components/editCh4Level.vue b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue new file mode 100644 index 0000000..717c30b --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editDigLevel.vue b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue new file mode 100644 index 0000000..84271be --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editGasLevel.vue b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue new file mode 100644 index 0000000..b890225 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue new file mode 100644 index 0000000..812966e --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue new file mode 100644 index 0000000..4449430 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue @@ -0,0 +1,299 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue new file mode 100644 index 0000000..ddd9433 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue @@ -0,0 +1,238 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editO2Level.vue b/src/views/systemConfig/alarmLevel/components/editO2Level.vue new file mode 100644 index 0000000..6879ec5 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editO2Level.vue @@ -0,0 +1,312 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editTempLevel.vue b/src/views/systemConfig/alarmLevel/components/editTempLevel.vue new file mode 100644 index 0000000..5300bd8 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editTempLevel.vue @@ -0,0 +1,312 @@ + + + + + + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/views/systemConfig/alarmLevel/components/editCh4Level.vue b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue new file mode 100644 index 0000000..717c30b --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editDigLevel.vue b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue new file mode 100644 index 0000000..84271be --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editGasLevel.vue b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue new file mode 100644 index 0000000..b890225 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue new file mode 100644 index 0000000..812966e --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue new file mode 100644 index 0000000..4449430 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue @@ -0,0 +1,299 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue new file mode 100644 index 0000000..ddd9433 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue @@ -0,0 +1,238 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editO2Level.vue b/src/views/systemConfig/alarmLevel/components/editO2Level.vue new file mode 100644 index 0000000..6879ec5 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editO2Level.vue @@ -0,0 +1,312 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editTempLevel.vue b/src/views/systemConfig/alarmLevel/components/editTempLevel.vue new file mode 100644 index 0000000..5300bd8 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editTempLevel.vue @@ -0,0 +1,312 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/listLevel.vue b/src/views/systemConfig/alarmLevel/listLevel.vue new file mode 100644 index 0000000..60d7d54 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/listLevel.vue @@ -0,0 +1,262 @@ + + + + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/views/systemConfig/alarmLevel/components/editCh4Level.vue b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue new file mode 100644 index 0000000..717c30b --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editDigLevel.vue b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue new file mode 100644 index 0000000..84271be --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editGasLevel.vue b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue new file mode 100644 index 0000000..b890225 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue new file mode 100644 index 0000000..812966e --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue new file mode 100644 index 0000000..4449430 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue @@ -0,0 +1,299 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue new file mode 100644 index 0000000..ddd9433 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue @@ -0,0 +1,238 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editO2Level.vue b/src/views/systemConfig/alarmLevel/components/editO2Level.vue new file mode 100644 index 0000000..6879ec5 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editO2Level.vue @@ -0,0 +1,312 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editTempLevel.vue b/src/views/systemConfig/alarmLevel/components/editTempLevel.vue new file mode 100644 index 0000000..5300bd8 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editTempLevel.vue @@ -0,0 +1,312 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/listLevel.vue b/src/views/systemConfig/alarmLevel/listLevel.vue new file mode 100644 index 0000000..60d7d54 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/listLevel.vue @@ -0,0 +1,262 @@ + + + + diff --git a/src/views/systemConfig/responsibleUser/editResponsibleUser.vue b/src/views/systemConfig/responsibleUser/editResponsibleUser.vue new file mode 100644 index 0000000..93bc404 --- /dev/null +++ b/src/views/systemConfig/responsibleUser/editResponsibleUser.vue @@ -0,0 +1,126 @@ + + + + + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/views/systemConfig/alarmLevel/components/editCh4Level.vue b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue new file mode 100644 index 0000000..717c30b --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editDigLevel.vue b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue new file mode 100644 index 0000000..84271be --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editGasLevel.vue b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue new file mode 100644 index 0000000..b890225 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue new file mode 100644 index 0000000..812966e --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue new file mode 100644 index 0000000..4449430 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue @@ -0,0 +1,299 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue new file mode 100644 index 0000000..ddd9433 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue @@ -0,0 +1,238 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editO2Level.vue b/src/views/systemConfig/alarmLevel/components/editO2Level.vue new file mode 100644 index 0000000..6879ec5 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editO2Level.vue @@ -0,0 +1,312 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editTempLevel.vue b/src/views/systemConfig/alarmLevel/components/editTempLevel.vue new file mode 100644 index 0000000..5300bd8 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editTempLevel.vue @@ -0,0 +1,312 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/listLevel.vue b/src/views/systemConfig/alarmLevel/listLevel.vue new file mode 100644 index 0000000..60d7d54 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/listLevel.vue @@ -0,0 +1,262 @@ + + + + diff --git a/src/views/systemConfig/responsibleUser/editResponsibleUser.vue b/src/views/systemConfig/responsibleUser/editResponsibleUser.vue new file mode 100644 index 0000000..93bc404 --- /dev/null +++ b/src/views/systemConfig/responsibleUser/editResponsibleUser.vue @@ -0,0 +1,126 @@ + + + + + diff --git a/src/views/systemConfig/responsibleUser/listResponsibleUser.vue b/src/views/systemConfig/responsibleUser/listResponsibleUser.vue new file mode 100644 index 0000000..7cc4654 --- /dev/null +++ b/src/views/systemConfig/responsibleUser/listResponsibleUser.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/views/systemConfig/alarmLevel/components/editCh4Level.vue b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue new file mode 100644 index 0000000..717c30b --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editDigLevel.vue b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue new file mode 100644 index 0000000..84271be --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editGasLevel.vue b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue new file mode 100644 index 0000000..b890225 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue new file mode 100644 index 0000000..812966e --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue new file mode 100644 index 0000000..4449430 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue @@ -0,0 +1,299 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue new file mode 100644 index 0000000..ddd9433 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue @@ -0,0 +1,238 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editO2Level.vue b/src/views/systemConfig/alarmLevel/components/editO2Level.vue new file mode 100644 index 0000000..6879ec5 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editO2Level.vue @@ -0,0 +1,312 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editTempLevel.vue b/src/views/systemConfig/alarmLevel/components/editTempLevel.vue new file mode 100644 index 0000000..5300bd8 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editTempLevel.vue @@ -0,0 +1,312 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/listLevel.vue b/src/views/systemConfig/alarmLevel/listLevel.vue new file mode 100644 index 0000000..60d7d54 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/listLevel.vue @@ -0,0 +1,262 @@ + + + + diff --git a/src/views/systemConfig/responsibleUser/editResponsibleUser.vue b/src/views/systemConfig/responsibleUser/editResponsibleUser.vue new file mode 100644 index 0000000..93bc404 --- /dev/null +++ b/src/views/systemConfig/responsibleUser/editResponsibleUser.vue @@ -0,0 +1,126 @@ + + + + + diff --git a/src/views/systemConfig/responsibleUser/listResponsibleUser.vue b/src/views/systemConfig/responsibleUser/listResponsibleUser.vue new file mode 100644 index 0000000..7cc4654 --- /dev/null +++ b/src/views/systemConfig/responsibleUser/listResponsibleUser.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/src/views/wellManage/addWell.vue b/src/views/wellManage/addWell.vue index fe77ad2..13a1f67 100644 --- a/src/views/wellManage/addWell.vue +++ b/src/views/wellManage/addWell.vue @@ -34,7 +34,7 @@ - + @@ -157,10 +157,10 @@ callback(new Error('请填写大于0的数字')) } else { const deep = parseFloat(value) - if (deep > 100 || deep < 0) { callback(new Error('请填写0到100数值')) } else { callback() } + if (deep > 10 || deep < 0) { callback(new Error('请填写0到10数值')) } else { callback() } } } else { - callback(new Error('井深不能为空')) + callback() } } const validateLng = (rule, value, callback) => { @@ -225,7 +225,7 @@ wellCode: [{ required: true, message: '窨井编号不能为空', trigger: ['blur', 'change'] }], wellName: [{ required: true, message: '窨井名称不能为空', trigger: ['blur', 'change'] }], position: [{ required: true, message: '窨井详细地址不能为空', trigger: ['blur', 'change'] }], - deep: [{ required: true, trigger: ['blur', 'change'], validator: validateDeep }], + deep: [{ required: false, trigger: ['blur', 'change'], validator: validateDeep }], coordinateX: [{ required: true, trigger: ['blur', 'change'], validator: validateLat }], coordinateY: [{ required: true, trigger: ['blur', 'change'], validator: validateLng }], deptid: [{ required: true, message: '组织机构必选', trigger: 'change' }], @@ -280,6 +280,7 @@ }, qu(val) { // 监控区变化 if (val !== '') { + this.wellForm.area = '' this.fetchArea2() } } @@ -375,7 +376,7 @@ } // 如果责任部门不选,则用权属作为责任部门 if (this.wellForm.responsibleDept === '') { - if (this.secondDeptTreeList.length > 0) { + if (this.secondDeptTreeList && this.secondDeptTreeList.length > 0) { this.$message.warning('必须选择维护机构') return } else { diff --git a/config/dev.env.js b/config/dev.env.js index c9afe29..aa233c5 100644 --- a/config/dev.env.js +++ b/config/dev.env.js @@ -9,7 +9,7 @@ // BASE_API: '"http://rest.apizza.net/mock/cfbb939c147bb6d68372de83af189fee/"', // BASE_API: '"http://106.74.146.218:2031"' // BASE_API: '"http://192.168.0.212:14537"' - BASE_API: '"http://138.198.17.115:20004/smartwell"' + BASE_API: '"http://139.198.17.115:20004/smartwell"' // BASE_API: '"http://192.168.0.225:8083"' // BASE_API: '"http://127.0.0.1:8083"' }) diff --git a/src/api/alarmRule.js b/src/api/alarmRule.js index 2e68297..0304ecb 100644 --- a/src/api/alarmRule.js +++ b/src/api/alarmRule.js @@ -44,3 +44,28 @@ data: params }) } +// 新增告警规则 +export function addAlarmRule(params) { + return request({ + url: 'alarmRule/add', + method: 'post', + params + }) +} +// 删除告警规则 +export function delAlarmRule(id) { + return request({ + url: 'alarmRule/delete', + method: 'post', + params: { + id: id + } + }) +} +// 待配置告警规则的设备列表 +export function getDeviceSimpleList(deviceType, configStatus) { + return request({ + url: 'alarmRule/getNoAlarmDevice', + method: 'get' + }) +} diff --git a/src/api/area.js b/src/api/area.js index a5a6b0d..974ce81 100644 --- a/src/api/area.js +++ b/src/api/area.js @@ -12,6 +12,14 @@ } }) } +// 区域查询 +export function getAreaListPage(params) { + return request({ + url: 'area/listPage', + method: 'get', + params + }) +} // 根据部门找其默认区域 export function getAreaByDept(deptid) { return request({ diff --git a/src/api/data.js b/src/api/data.js index 7be32bb..39e6c9b 100644 --- a/src/api/data.js +++ b/src/api/data.js @@ -10,7 +10,6 @@ params }) } - // 液位数据查询 export function getLiquidData(params) { return request({ @@ -27,7 +26,6 @@ params }) } - // 开挖数据查询 export function getDigData(params) { return request({ @@ -36,7 +34,6 @@ params }) } - // 有害气体数据查询 export function getHarmfulData(params) { return request({ @@ -45,7 +42,6 @@ params }) } - // 温湿度数据查询 export function getTempData(params) { return request({ @@ -54,7 +50,6 @@ params }) } - // 井盖定位监测仪数据查询 export function getWellLocaData(params) { return request({ @@ -140,3 +135,4 @@ responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + diff --git a/src/api/device.js b/src/api/device.js index 63fe6ec..1e22a69 100644 --- a/src/api/device.js +++ b/src/api/device.js @@ -68,6 +68,7 @@ return request({ url: 'device/batchImport', method: 'post', + timeout: 240000, headers: { 'Content-Type': 'multipart/form-data' }, data: param }) diff --git a/src/api/well.js b/src/api/well.js index 127bcca..a7261ee 100644 --- a/src/api/well.js +++ b/src/api/well.js @@ -73,15 +73,26 @@ }) } // 批量导出 -export function batchExportWell(params) { +export function batchExportWell(params, config) { return request({ url: 'well/batchExport', method: 'get', timeout: 120000, params, + ...config, responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob }) } + +// export function batchExportWell(params) { +// return request({ +// url: 'well/batchExport', +// method: 'get', +// timeout: 120000, +// params, +// responseType: 'blob' // 这一步也很关键,一定要加上 responseType 值为 blob +// }) +// } // 获取某井内监控数据 export function watchDataByWell(id) { return request({ diff --git a/src/assets/audio/alarm.mp3 b/src/assets/audio/alarm.mp3 new file mode 100644 index 0000000..f376e89 --- /dev/null +++ b/src/assets/audio/alarm.mp3 Binary files differ diff --git a/src/assets/global_images/chartSample.png b/src/assets/global_images/chartSample.png new file mode 100644 index 0000000..a6e516a --- /dev/null +++ b/src/assets/global_images/chartSample.png Binary files differ diff --git a/src/assets/global_images/header.png b/src/assets/global_images/header.png new file mode 100644 index 0000000..4d694a8 --- /dev/null +++ b/src/assets/global_images/header.png Binary files differ diff --git a/src/components/Progressor/progressor.vue b/src/components/Progressor/progressor.vue new file mode 100644 index 0000000..4a2631c --- /dev/null +++ b/src/components/Progressor/progressor.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/views/systemConfig/alarmLevel/components/editCh4Level.vue b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue new file mode 100644 index 0000000..717c30b --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editDigLevel.vue b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue new file mode 100644 index 0000000..84271be --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editGasLevel.vue b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue new file mode 100644 index 0000000..b890225 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue new file mode 100644 index 0000000..812966e --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue new file mode 100644 index 0000000..4449430 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue @@ -0,0 +1,299 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue new file mode 100644 index 0000000..ddd9433 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue @@ -0,0 +1,238 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editO2Level.vue b/src/views/systemConfig/alarmLevel/components/editO2Level.vue new file mode 100644 index 0000000..6879ec5 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editO2Level.vue @@ -0,0 +1,312 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editTempLevel.vue b/src/views/systemConfig/alarmLevel/components/editTempLevel.vue new file mode 100644 index 0000000..5300bd8 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editTempLevel.vue @@ -0,0 +1,312 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/listLevel.vue b/src/views/systemConfig/alarmLevel/listLevel.vue new file mode 100644 index 0000000..60d7d54 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/listLevel.vue @@ -0,0 +1,262 @@ + + + + diff --git a/src/views/systemConfig/responsibleUser/editResponsibleUser.vue b/src/views/systemConfig/responsibleUser/editResponsibleUser.vue new file mode 100644 index 0000000..93bc404 --- /dev/null +++ b/src/views/systemConfig/responsibleUser/editResponsibleUser.vue @@ -0,0 +1,126 @@ + + + + + diff --git a/src/views/systemConfig/responsibleUser/listResponsibleUser.vue b/src/views/systemConfig/responsibleUser/listResponsibleUser.vue new file mode 100644 index 0000000..7cc4654 --- /dev/null +++ b/src/views/systemConfig/responsibleUser/listResponsibleUser.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/src/views/wellManage/addWell.vue b/src/views/wellManage/addWell.vue index fe77ad2..13a1f67 100644 --- a/src/views/wellManage/addWell.vue +++ b/src/views/wellManage/addWell.vue @@ -34,7 +34,7 @@ - + @@ -157,10 +157,10 @@ callback(new Error('请填写大于0的数字')) } else { const deep = parseFloat(value) - if (deep > 100 || deep < 0) { callback(new Error('请填写0到100数值')) } else { callback() } + if (deep > 10 || deep < 0) { callback(new Error('请填写0到10数值')) } else { callback() } } } else { - callback(new Error('井深不能为空')) + callback() } } const validateLng = (rule, value, callback) => { @@ -225,7 +225,7 @@ wellCode: [{ required: true, message: '窨井编号不能为空', trigger: ['blur', 'change'] }], wellName: [{ required: true, message: '窨井名称不能为空', trigger: ['blur', 'change'] }], position: [{ required: true, message: '窨井详细地址不能为空', trigger: ['blur', 'change'] }], - deep: [{ required: true, trigger: ['blur', 'change'], validator: validateDeep }], + deep: [{ required: false, trigger: ['blur', 'change'], validator: validateDeep }], coordinateX: [{ required: true, trigger: ['blur', 'change'], validator: validateLat }], coordinateY: [{ required: true, trigger: ['blur', 'change'], validator: validateLng }], deptid: [{ required: true, message: '组织机构必选', trigger: 'change' }], @@ -280,6 +280,7 @@ }, qu(val) { // 监控区变化 if (val !== '') { + this.wellForm.area = '' this.fetchArea2() } } @@ -375,7 +376,7 @@ } // 如果责任部门不选,则用权属作为责任部门 if (this.wellForm.responsibleDept === '') { - if (this.secondDeptTreeList.length > 0) { + if (this.secondDeptTreeList && this.secondDeptTreeList.length > 0) { this.$message.warning('必须选择维护机构') return } else { diff --git a/src/views/wellManage/detailWell.vue b/src/views/wellManage/detailWell.vue index 38f9d85..4203c38 100644 --- a/src/views/wellManage/detailWell.vue +++ b/src/views/wellManage/detailWell.vue @@ -56,6 +56,12 @@
+ + + + + +
- +
@@ -117,7 +123,7 @@ - + @@ -146,184 +152,181 @@ diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/views/systemConfig/alarmLevel/components/editCh4Level.vue b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue new file mode 100644 index 0000000..717c30b --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editDigLevel.vue b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue new file mode 100644 index 0000000..84271be --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editGasLevel.vue b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue new file mode 100644 index 0000000..b890225 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue new file mode 100644 index 0000000..812966e --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue new file mode 100644 index 0000000..4449430 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue @@ -0,0 +1,299 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue new file mode 100644 index 0000000..ddd9433 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue @@ -0,0 +1,238 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editO2Level.vue b/src/views/systemConfig/alarmLevel/components/editO2Level.vue new file mode 100644 index 0000000..6879ec5 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editO2Level.vue @@ -0,0 +1,312 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editTempLevel.vue b/src/views/systemConfig/alarmLevel/components/editTempLevel.vue new file mode 100644 index 0000000..5300bd8 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editTempLevel.vue @@ -0,0 +1,312 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/listLevel.vue b/src/views/systemConfig/alarmLevel/listLevel.vue new file mode 100644 index 0000000..60d7d54 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/listLevel.vue @@ -0,0 +1,262 @@ + + + + diff --git a/src/views/systemConfig/responsibleUser/editResponsibleUser.vue b/src/views/systemConfig/responsibleUser/editResponsibleUser.vue new file mode 100644 index 0000000..93bc404 --- /dev/null +++ b/src/views/systemConfig/responsibleUser/editResponsibleUser.vue @@ -0,0 +1,126 @@ + + + + + diff --git a/src/views/systemConfig/responsibleUser/listResponsibleUser.vue b/src/views/systemConfig/responsibleUser/listResponsibleUser.vue new file mode 100644 index 0000000..7cc4654 --- /dev/null +++ b/src/views/systemConfig/responsibleUser/listResponsibleUser.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/src/views/wellManage/addWell.vue b/src/views/wellManage/addWell.vue index fe77ad2..13a1f67 100644 --- a/src/views/wellManage/addWell.vue +++ b/src/views/wellManage/addWell.vue @@ -34,7 +34,7 @@ - + @@ -157,10 +157,10 @@ callback(new Error('请填写大于0的数字')) } else { const deep = parseFloat(value) - if (deep > 100 || deep < 0) { callback(new Error('请填写0到100数值')) } else { callback() } + if (deep > 10 || deep < 0) { callback(new Error('请填写0到10数值')) } else { callback() } } } else { - callback(new Error('井深不能为空')) + callback() } } const validateLng = (rule, value, callback) => { @@ -225,7 +225,7 @@ wellCode: [{ required: true, message: '窨井编号不能为空', trigger: ['blur', 'change'] }], wellName: [{ required: true, message: '窨井名称不能为空', trigger: ['blur', 'change'] }], position: [{ required: true, message: '窨井详细地址不能为空', trigger: ['blur', 'change'] }], - deep: [{ required: true, trigger: ['blur', 'change'], validator: validateDeep }], + deep: [{ required: false, trigger: ['blur', 'change'], validator: validateDeep }], coordinateX: [{ required: true, trigger: ['blur', 'change'], validator: validateLat }], coordinateY: [{ required: true, trigger: ['blur', 'change'], validator: validateLng }], deptid: [{ required: true, message: '组织机构必选', trigger: 'change' }], @@ -280,6 +280,7 @@ }, qu(val) { // 监控区变化 if (val !== '') { + this.wellForm.area = '' this.fetchArea2() } } @@ -375,7 +376,7 @@ } // 如果责任部门不选,则用权属作为责任部门 if (this.wellForm.responsibleDept === '') { - if (this.secondDeptTreeList.length > 0) { + if (this.secondDeptTreeList && this.secondDeptTreeList.length > 0) { this.$message.warning('必须选择维护机构') return } else { diff --git a/src/views/wellManage/detailWell.vue b/src/views/wellManage/detailWell.vue index 38f9d85..4203c38 100644 --- a/src/views/wellManage/detailWell.vue +++ b/src/views/wellManage/detailWell.vue @@ -56,6 +56,12 @@
+ + + + + +
- +
@@ -117,7 +123,7 @@
- + @@ -146,184 +152,181 @@ diff --git a/src/components/SelectTree/singleSelect.vue b/src/components/SelectTree/singleSelect.vue index 85917ce..ea76aff 100644 --- a/src/components/SelectTree/singleSelect.vue +++ b/src/components/SelectTree/singleSelect.vue @@ -33,187 +33,187 @@ \ No newline at end of file diff --git a/src/icons/svg/icon-smart.svg b/src/icons/svg/icon-smart.svg new file mode 100644 index 0000000..58ea91c --- /dev/null +++ b/src/icons/svg/icon-smart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/icon-sysconfig.svg b/src/icons/svg/icon-sysconfig.svg new file mode 100644 index 0000000..56f04c6 --- /dev/null +++ b/src/icons/svg/icon-sysconfig.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/svg/well-common-red.svg b/src/icons/svg/well-common-red.svg new file mode 100644 index 0000000..86043f8 --- /dev/null +++ b/src/icons/svg/well-common-red.svg @@ -0,0 +1 @@ + diff --git a/src/main.js b/src/main.js index e85ba70..91f9c7d 100644 --- a/src/main.js +++ b/src/main.js @@ -27,13 +27,14 @@ import 'babel-polyfill' // import '../mock' // simulation data -import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation } from './utils/permission' +import { hasPermission, showWellType, showDeviceType, showIpConfig, isOperation, isAdministrator } from './utils/permission' Vue.prototype.hasPerm = hasPermission Vue.prototype.showWellType = showWellType Vue.prototype.showDeviceType = showDeviceType Vue.prototype.showIpConfig = showIpConfig Vue.prototype.isOperation = isOperation +Vue.prototype.isAdministrator = isAdministrator // 引入Element-ui Vue.use(ElementUI, { locale }) @@ -59,3 +60,29 @@ render: h => h(App) }) +// 引入音频文件 +import audio from '@/assets/audio/alarm.mp3' + +// 方法1:注册播放音频事件到Vue实例上 +Vue.prototype.playAudio = (audioName) => { + const buttonAudio = document.getElementById('eventAudio') + buttonAudio.setAttribute('src', audio) + console.log(buttonAudio) + const playPromise = buttonAudio.play() + if (playPromise) { + playPromise.then(() => { + // 音频加载成功 + console.log('音频加载成功') + }).catch((e) => { + // 音频加载失败 + console.error(e.message) + }) + } + if (buttonAudio.paused === true) { + buttonAudio.load() + } else { + buttonAudio.pause() + buttonAudio.play() + } +} + diff --git a/src/router/index.js b/src/router/index.js index f269b02..195cf4f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -73,7 +73,7 @@ component: Layout, redirect: '/overview', meta: { - title: '闸井状态总览', + title: '窨井状态总览', icon: 'icon-config', // 图标 permission: ['/overview']// 权限名称 }, @@ -82,7 +82,7 @@ path: '/overview', component: () => import('@/views/overview/overview'), name: 'overview', - meta: { title: '闸井状态总览', icon: 'icon-config', permission: ['/overview'] } + meta: { title: '窨井状态总览', icon: 'icon-config', permission: ['/overview'] } } ] }, @@ -161,13 +161,13 @@ path: '/wellList', name: 'WellList', component: () => import('@/views/wellManage/listWell'), - meta: { title: '闸井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } + meta: { title: '窨井列表', icon: 'icon-config', keepAlive: true, permission: ['/well/list'] } }, { path: '/addWell', name: 'AddWell', component: () => import('@/views/wellManage/addWell'), - meta: { title: '新增闸井', icon: 'icon-config', permission: ['/well/add'] } + meta: { title: '新增窨井', icon: 'icon-config', permission: ['/well/add'] } } ] }, @@ -309,5 +309,31 @@ } ] }, + { + path: 'systemConfig', + component: Layout, + redirect: '/', + name: 'SystemConfig', + alwaysShow: true, + meta: { + title: '系统配置', + icon: 'icon-config', // 图标 + permission: ['/sysconfig']// 权限名称 + }, + children: [ + { + path: '/responsibleUser', + name: 'ResponsibleUser', + component: () => import('@/views/systemConfig/responsibleUser/listResponsibleUser'), + meta: { title: '联系人配置', icon: 'function', permission: ['/responsibleUser'] } + }, + { + path: '/alarmLevel', + name: 'AlarmLevel', + component: () => import('@/views/systemConfig/alarmLevel/listLevel'), + meta: { title: '告警等级', icon: 'function', permission: ['/alarmLevel'] } + } + ] + }, { path: '*', redirect: '/404', hidden: true } ] diff --git a/src/store/getters.js b/src/store/getters.js index 20a98dc..937bbf9 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -7,6 +7,8 @@ publicKey: state => state.app.publicKey, // 公钥 sid: state => state.app.sid, // 用户标识 token: state => state.user.token, // token + id: state => state.user.id, // id + account: state => state.user.account, // 账户 name: state => state.user.name, // 姓名 roleList: state => state.user.roleList, // 角色列表 roleNames: state => state.user.roleNames, // 角色名称列表 diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index 72d6c17..abd4b21 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -89,7 +89,6 @@ actions: { // 获取用户权限 GetMenus({ commit, state }) { - console.log('in store.permission.js:GetMenus:') return new Promise((resolve, reject) => { getMenus(state.token).then(response => { // 处理返回值 const data = response.data diff --git a/src/store/modules/user.js b/src/store/modules/user.js index 265da3c..c0bf1fe 100644 --- a/src/store/modules/user.js +++ b/src/store/modules/user.js @@ -4,6 +4,8 @@ const user = { state: { token: getToken(), + id: '', // 用户id + account: '', // 用户名 name: '', // 姓名 deptId: '', // 部门编号 deptName: '', // 部门名称 @@ -21,6 +23,12 @@ SET_TOKEN: (state, token) => { state.token = token }, + SET_ID: (state, id) => { + state.id = id + }, + SET_ACCOUNT: (state, account) => { + state.account = account + }, SET_NAME: (state, name) => { state.name = name }, @@ -96,6 +104,8 @@ } else { reject('该用户无组织机构') } + commit('SET_ID', data.id) + commit('SET_ACCOUNT', data.account) commit('SET_NAME', data.name) resolve(response) }).catch(error => { diff --git a/src/styles/index.scss b/src/styles/index.scss index 9b6d2a6..a42818a 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -86,3 +86,12 @@ .el-main{ height: calc(100vh - 50px); } +.search-div{ + margin-bottom: 10px; +} +.search-div .el-form-item { + margin-bottom:10px !important; +} +.clear-float{ + clear:both +} diff --git a/src/utils/parseutils.js b/src/utils/parseutils.js new file mode 100644 index 0000000..d895fa8 --- /dev/null +++ b/src/utils/parseutils.js @@ -0,0 +1,31 @@ +// 解析工具 + +/** + * 根据路径解析url参数 + * @param url 待解析路径 + * @return params 参数对象或是null + */ +export function parseUrl(url) { + // url样式如:xxxxx.com/api?key1=value1&key2=value2 + // 分割url中?前后字符串,有问号的表示有参数 + const query = url.split('?') + // 如果query长度大于1 表示有参数 + if (query.length > 1) { + const paramsObject = {} + // 将参数字符串用&分割,key1=value1&key2=value2 + const paramsStr = query[1].split('&') + // 遍历所有参数 + for (let i = 0; i < paramsStr.length; i++) { + const paramStr = paramsStr[i] // 请求参数,key=value + // 将参数的key和value分割 + const pos = paramStr.indexOf('=') + if (pos === -1) continue + const key = paramStr.substring(0, pos) // 获得参数名 + const value = paramStr.substring(pos + 1) // 获得参数值 + paramsObject[key] = value + } + return paramsObject + } else { + return null + } +} diff --git a/src/utils/permission.js b/src/utils/permission.js index 8fee27f..b325ab0 100644 --- a/src/utils/permission.js +++ b/src/utils/permission.js @@ -1,7 +1,7 @@ import store from '../store' /** * 判断是否有权限 - */ + */ export function hasPermission(permission) { const btns = store.getters.btns return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false @@ -38,7 +38,16 @@ // 判断用户是否为运维人员或其他管理员 export function isOperation() { const roleTips = store.getters.roleTips + console.log(roleTips) return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false return (tip === 'operation' || tip === 'administrator') }) } +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) +} diff --git a/src/utils/request.js b/src/utils/request.js index 28ffa69..10fcaa7 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -40,19 +40,22 @@ } else if (res.code !== 200) { // 判断状态码 // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; if (res.code === 401 || res.code === 50012 || res.code === 50014) { - MessageBox.confirm( - '你已被登出,可以取消继续留在该页面,或者重新登录', - '确定登出', - { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - store.dispatch('FedLogOut').then(() => { - location.reload() // 为了重新实例化vue-router对象 避免bug - }) + store.dispatch('FedLogOut').then(() => { + location.reload() // 为了重新实例化vue-router对象 避免bug }) + // MessageBox.confirm( + // '你已被登出,可以取消继续留在该页面,或者重新登录', + // '确定登出', + // { + // confirmButtonText: '重新登录', + // cancelButtonText: '取消', + // type: 'warning' + // } + // ).then(() => { + // store.dispatch('FedLogOut').then(() => { + // location.reload() // 为了重新实例化vue-router对象 避免bug + // }) + // }) } else { Message({ showClose: true, diff --git a/src/utils/security.js b/src/utils/security.js index b2434a2..aca601c 100644 --- a/src/utils/security.js +++ b/src/utils/security.js @@ -17,7 +17,6 @@ store.dispatch('GetConfig').then(() => { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes }).catch((e) => { this.loading = false @@ -25,7 +24,6 @@ } else { encrypt.setPublicKey(store.getters.publicKey)// 从store中读取公钥 var enRes = encrypt.encrypt(value) - console.log('加密结果为:' + enRes) return enRes } } diff --git a/src/utils/string.js b/src/utils/string.js new file mode 100644 index 0000000..92a860e --- /dev/null +++ b/src/utils/string.js @@ -0,0 +1,56 @@ +// 比较日期,时间大小 +export function compareCalendar(t1, t2) { + if (t1.indexOf(' ') !== -1 && t2.indexOf(' ') !== -1) { + // 包含时间,日期 + return compareTime(t1, t2) + } else { + // 不包含时间,只包含日期 + return compareDate(t1, t2) + } +} + +// 比较日期大小 +function compareDate(logintime, logouttime) { + var arys1 = [] + var arys2 = [] + if (logintime != null && logouttime != null) { + arys1 = logintime.split('-') + var logindate = new Date(arys1[0], parseInt(arys1[1] - 1), arys1[2]) + arys2 = logouttime.split('-') + var logoutdate = new Date(arys2[0], parseInt(arys2[1] - 1), arys2[2]) + if (logindate > logoutdate) { + return -1 + } else if (logindate === logoutdate) { + return 0 + } else { + return 1 + } + } +} + +// 判断日期,时间大小 +function compareTime(logintime, logouttime) { + if (logintime.length > 0 && logouttime.length > 0) { + var logintimeTemp = logintime.split(' ') + var logouttimeTemp = logouttime.split(' ') + + var arrloginDate = logintimeTemp[0].split('-') + var arrlogoutDate = logouttimeTemp[0].split('-') + + var arrloginTime = logintimeTemp[1].split(':') + var arrlogoutTime = logouttimeTemp[1].split(':') + + var allLoginDate = new Date(arrloginDate[0], arrloginDate[1], arrloginDate[2], arrloginTime[0], arrloginTime[1], arrloginTime[2]) + var allLogoutDate = new Date(arrlogoutDate[0], arrlogoutDate[1], arrlogoutDate[2], arrlogoutTime[0], arrlogoutTime[1], arrlogoutTime[2]) + + if (allLoginDate.getTime() > allLogoutDate.getTime()) { + return -1 + } else if (allLoginDate.getTime() === allLogoutDate.getTime()) { + return 0 + } else { + return 1 + } + } else { + return -1 + } +} diff --git a/src/utils/structure.js b/src/utils/structure.js index 34a6672..b325ab0 100644 --- a/src/utils/structure.js +++ b/src/utils/structure.js @@ -1,135 +1,53 @@ -// 数据结构转换工具 - +import store from '../store' /** - * 判断是否有转树的必要 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @returns {boolean} 有返回true,无返回false + * 判断是否有权限 */ -export function judgeTree(plainList, id = '0') { - if (plainList && plainList.length > 0) { - let flag = false // 是否需要转成树结构 - const pid = plainList[0].pid - for (const item of plainList) { - if (item.pid !== pid) { - flag = true - break - } - } - return flag - } else { return false } +export function hasPermission(permission) { + const btns = store.getters.btns + return btns.some(btn => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return btn.url === permission + }) +} +// 根据用户权限判断是否要显示井类型下拉框 +export function showWellType() { + console.log('是否显示井类型下拉') + const wellTypes = store.getters.wellTypes + if (wellTypes.length > 1) return true + else return false } -/** - * 平面数据数据转树结构 - * @param plainList 平行数据列表 - * @param id 祖宗id - * @param isSelect 是否是下拉需要顶级的树 - * @returns {*} - */ -export function toTreeList(plainList, id = '0', isSelect = false) { - const pid = findPid(plainList) - if (pid.length > 1) { - return plainList - } else { - const tree = cleanChildren(buildTree(plainList, pid[0], isSelect)) - return tree - } +// 根据用户权限判断是否要显示设备类型下拉框 +export function showDeviceType() { + const deviceTypes = store.getters.deviceTypes + if (deviceTypes.length > 1) return true + else return false } -// 构建树 -function buildTree(plainList, id = '0', isSelect) { - // 递归函数 - const fa = (parentId) => { - const temp = [] - for (let i = 0; i < plainList.length; i++) { - const n = plainList[i] - const id = '' + n.id - const pid = '' + n.pid - if (pid === parentId) { - n.children = fa(id) - temp.push(n) - } - } - return temp - } - // 如果是下拉框需要使用的树,首先寻找顶级,将顶级也放入列表 - if (isSelect) { - let flag = 1 - const list = [] - for (const n of plainList) { - const nid = '' + n.id - if (nid === id) { - n.children = fa(id) - flag = 0 - list.push(n) - return list - } - } if (flag === 1) { // 没有找到父级,按原流程走 - return fa(id) - } - } else { - return fa(id) - } +// 根据用户权限判断是否要显示IP配置项,集中器不显示ip +export function showIpConfig() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要没有1(集中器)就是返回true + return communication !== '1' + }) } - -// 清除空 children项 -function cleanChildren(data) { - const fa = (list) => { - list.map((e) => { - if (e && e.children && e.children.length) { - fa(e.children) - } else { - delete e.children - } - return e - }) - return list - } - return fa(data) +export function notContainConcentrator() { + const communications = store.getters.communications + return communications.some(communication => { // 遍历通讯方式,只要有1(集中器)就是返回true + return communication === '1' + }) } - -function findPid(plainList) { - const pidList = new Set() - for (const item of plainList) { - pidList.add(item.pid) - } - for (const item of plainList) { - if (pidList.has(item.id)) { - pidList.delete(item.id) - } - } - var arr = [...pidList] - return arr +// 判断用户是否为运维人员或其他管理员 +export function isOperation() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'operation' || tip === 'administrator') + }) } - -// 平面数据数据转树结构 -export function getShowItem(plainList, id = '0') { - const expandList = [] - const openedList = [] - for (let i = 0; i < plainList.length; i++) { - if (plainList[i].open === 'true' || plainList[i].open === true) { - expandList.push(plainList[i].id) - } - if (plainList[i].checked === 'true' || plainList[i].checked === true) { - openedList.push(plainList[i].id) - } - } - return [expandList, openedList] -} - -// 从树列表中删除指定元素 -export function deleteItem(list, des) { - const del = (list, item) => { - for (const i in list) { - if (list[i].id === des.id) { - list.splice(i, 1) - return - } else { - if (list[i].children && list[i].children.length > 0) { - del(list[i].children, des) - } - } - } - } - del(list, des) +// 判断是不是超级管理员 +export function isAdministrator() { + const roleTips = store.getters.roleTips + console.log(roleTips) + return roleTips.some(tip => { // 遍历btns,查找btn.url是否有匹配的permission,有则返回true,否则返回false + return (tip === 'administrator') + }) } diff --git a/src/views/alarmManage/components/HandlePrompt.vue b/src/views/alarmManage/components/HandlePrompt.vue index a4f9553..d802514 100644 --- a/src/views/alarmManage/components/HandlePrompt.vue +++ b/src/views/alarmManage/components/HandlePrompt.vue @@ -2,11 +2,11 @@ - + + placeholder="请输入详细的告警取消原因"/> @@ -50,15 +50,16 @@ isBatch: false, // 是不是批量删除 dialogVisible: false, closeReasons: [{ - value: '4', - label: '已取消' - }, { value: '3', - label: '已完成' + label: '已处理' // 已完成 + }, { + value: '4', + label: '无需处理' // 已取消 }], rules: { jobStatus: [{ required: true, message: '关闭原因必选', trigger: ['blur', 'change'] }], - handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }] + handleMessage: [{ required: true, message: '备注不得为空', trigger: ['blur', 'change'] }, + { min: 1, max: 30, message: '长度不得超过30字', trigger: 'blur' }] }, value: '' } @@ -88,30 +89,34 @@ }, // 取消报警,调用结束工单接口 cancelAlarm() { - this.$confirm( - '确定要取消报警吗?', - '确认操作', - { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - } - ).then(() => { - // 批量消警接口 - if (this.isBatch) { - batchCancel(this.formData).then(response => { - this.$message.success('批量消警成功') - this.closeDialog() - }) - } else { // 单个消警接口 - const formData = { - id: this.formData.id, - jobStatus: this.formData.jobStatus, // 工单状态 - handleMessage: this.formData.handleMessage // 原因 - } - cancelAlarm(formData).then(response => { - this.$message.success('取消报警成功') - this.closeDialog() + this.$refs['form'].validate((valid) => { + if (valid) { + this.$confirm( + '确定要取消报警吗?', + '确认操作', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + } + ).then(() => { + // 批量消警接口 + if (this.isBatch) { + batchCancel(this.formData).then(response => { + this.$message.success('批量消警成功') + this.closeDialog() + }) + } else { // 单个消警接口 + const formData = { + id: this.formData.id, + jobStatus: this.formData.jobStatus, // 工单状态 + handleMessage: this.formData.handleMessage // 原因 + } + cancelAlarm(formData).then(response => { + this.$message.success('取消报警成功') + this.closeDialog() + }) + } }) } }) diff --git a/src/views/alarmManage/listAlarmNow.vue b/src/views/alarmManage/listAlarmNow.vue index cccc668..c9c1b37 100644 --- a/src/views/alarmManage/listAlarmNow.vue +++ b/src/views/alarmManage/listAlarmNow.vue @@ -234,12 +234,16 @@ // 取消报警 cancelAlarm(jobId) { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, jobId, false) + // }, 100) }, // 取消报警,调用结束工单接口 batchCancel() { this.cancelShow = true + // setTimeout(function() { this.$refs.handlePrompt.initDialog(true, '', true, this.listQuery) + // }, 100) }, formatValue(cellValue) { if (cellValue === 1) { @@ -249,7 +253,7 @@ } else if (cellValue === 3) { return '三级告警' } else { - return '' + return '--' } }, // 计算行样式,不同等级显示不同颜色,暂时不用了 @@ -289,7 +293,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, checkCell(value) { diff --git a/src/views/alarmManage/listAlarmRecords.vue b/src/views/alarmManage/listAlarmRecords.vue index bea7c75..384f342 100644 --- a/src/views/alarmManage/listAlarmRecords.vue +++ b/src/views/alarmManage/listAlarmRecords.vue @@ -50,7 +50,8 @@ @@ -124,6 +125,12 @@ align: 'center' }, { + text: '告警等级', + value: 'alarmLevel', + align: 'center', + level: true + }, + { text: '告警原因', value: 'alarmContentName', align: 'center' @@ -201,8 +208,8 @@ next() }, mounted() { - if (this.$route.窨井 && this.$route.窨井.wellCode) { - this.listQuery.keywords = this.$route.窨井.wellCode + if (this.$route.query && this.$route.query.wellCode) { + this.listQuery.keywords = this.$route.query.wellCode this.fetchData(false) } else { this.listQuery.keywords = '' @@ -215,6 +222,7 @@ } }, activated() { + console.log('alarmRecored actived') if (!isFromDetail) { if (this.$route.query && this.$route.query.wellCode) { this.listQuery.keywords = this.$route.query.wellCode @@ -236,6 +244,17 @@ this.wellShow = true this.$refs.wellInfo.initDialog(row.wellId) }, + formatValue(cellValue) { + if (cellValue === 1) { + return '一级告警' + } else if (cellValue === 2) { + return '二级告警' + } else if (cellValue === 3) { + return '三级告警' + } else { + return '--' + } + }, // 工单 showJob(row) { const jobId = row.jobId @@ -264,7 +283,7 @@ window.URL.revokeObjectURL(href) // 释放blob对象 }).catch((res) => { loading.close() - // this.$message.error(res.message) + this.$message.error(res.message) }) }, // 查询数据 diff --git a/src/views/alarmRule/alarmRule.vue b/src/views/alarmRule/alarmRule.vue new file mode 100644 index 0000000..0201880 --- /dev/null +++ b/src/views/alarmRule/alarmRule.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/views/alarmRule/components/editRule.vue b/src/views/alarmRule/components/editRule.vue new file mode 100644 index 0000000..d29d47a --- /dev/null +++ b/src/views/alarmRule/components/editRule.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/src/views/alarmRule/components/listRule.vue b/src/views/alarmRule/components/listRule.vue new file mode 100644 index 0000000..d13e743 --- /dev/null +++ b/src/views/alarmRule/components/listRule.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/src/views/alarmRule/editRule.vue b/src/views/alarmRule/editRule.vue index dc61a71..e052117 100644 --- a/src/views/alarmRule/editRule.vue +++ b/src/views/alarmRule/editRule.vue @@ -1,7 +1,7 @@ + + diff --git a/src/views/systemConfig/alarmLevel/components/editCh4Level.vue b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue new file mode 100644 index 0000000..717c30b --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editCh4Level.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editDigLevel.vue b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue new file mode 100644 index 0000000..84271be --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editDigLevel.vue @@ -0,0 +1,237 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editGasLevel.vue b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue new file mode 100644 index 0000000..b890225 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editGasLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue new file mode 100644 index 0000000..812966e --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editH2sLevel.vue @@ -0,0 +1,240 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue new file mode 100644 index 0000000..4449430 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editHumiLevel.vue @@ -0,0 +1,299 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue new file mode 100644 index 0000000..ddd9433 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editLiquidLevel.vue @@ -0,0 +1,238 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editO2Level.vue b/src/views/systemConfig/alarmLevel/components/editO2Level.vue new file mode 100644 index 0000000..6879ec5 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editO2Level.vue @@ -0,0 +1,312 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/components/editTempLevel.vue b/src/views/systemConfig/alarmLevel/components/editTempLevel.vue new file mode 100644 index 0000000..5300bd8 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/components/editTempLevel.vue @@ -0,0 +1,312 @@ + + + + + + diff --git a/src/views/systemConfig/alarmLevel/listLevel.vue b/src/views/systemConfig/alarmLevel/listLevel.vue new file mode 100644 index 0000000..60d7d54 --- /dev/null +++ b/src/views/systemConfig/alarmLevel/listLevel.vue @@ -0,0 +1,262 @@ + + + + diff --git a/src/views/systemConfig/responsibleUser/editResponsibleUser.vue b/src/views/systemConfig/responsibleUser/editResponsibleUser.vue new file mode 100644 index 0000000..93bc404 --- /dev/null +++ b/src/views/systemConfig/responsibleUser/editResponsibleUser.vue @@ -0,0 +1,126 @@ + + + + + diff --git a/src/views/systemConfig/responsibleUser/listResponsibleUser.vue b/src/views/systemConfig/responsibleUser/listResponsibleUser.vue new file mode 100644 index 0000000..7cc4654 --- /dev/null +++ b/src/views/systemConfig/responsibleUser/listResponsibleUser.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/src/views/wellManage/addWell.vue b/src/views/wellManage/addWell.vue index fe77ad2..13a1f67 100644 --- a/src/views/wellManage/addWell.vue +++ b/src/views/wellManage/addWell.vue @@ -34,7 +34,7 @@ - + @@ -157,10 +157,10 @@ callback(new Error('请填写大于0的数字')) } else { const deep = parseFloat(value) - if (deep > 100 || deep < 0) { callback(new Error('请填写0到100数值')) } else { callback() } + if (deep > 10 || deep < 0) { callback(new Error('请填写0到10数值')) } else { callback() } } } else { - callback(new Error('井深不能为空')) + callback() } } const validateLng = (rule, value, callback) => { @@ -225,7 +225,7 @@ wellCode: [{ required: true, message: '窨井编号不能为空', trigger: ['blur', 'change'] }], wellName: [{ required: true, message: '窨井名称不能为空', trigger: ['blur', 'change'] }], position: [{ required: true, message: '窨井详细地址不能为空', trigger: ['blur', 'change'] }], - deep: [{ required: true, trigger: ['blur', 'change'], validator: validateDeep }], + deep: [{ required: false, trigger: ['blur', 'change'], validator: validateDeep }], coordinateX: [{ required: true, trigger: ['blur', 'change'], validator: validateLat }], coordinateY: [{ required: true, trigger: ['blur', 'change'], validator: validateLng }], deptid: [{ required: true, message: '组织机构必选', trigger: 'change' }], @@ -280,6 +280,7 @@ }, qu(val) { // 监控区变化 if (val !== '') { + this.wellForm.area = '' this.fetchArea2() } } @@ -375,7 +376,7 @@ } // 如果责任部门不选,则用权属作为责任部门 if (this.wellForm.responsibleDept === '') { - if (this.secondDeptTreeList.length > 0) { + if (this.secondDeptTreeList && this.secondDeptTreeList.length > 0) { this.$message.warning('必须选择维护机构') return } else { diff --git a/src/views/wellManage/detailWell.vue b/src/views/wellManage/detailWell.vue index 38f9d85..4203c38 100644 --- a/src/views/wellManage/detailWell.vue +++ b/src/views/wellManage/detailWell.vue @@ -56,6 +56,12 @@
+ + + + + +
- +
@@ -117,7 +123,7 @@
- + @@ -146,184 +152,181 @@