Преглед на файлове

智慧运维接口接入

viviandjava преди 5 месеца
родител
ревизия
d3c12c285e

+ 1 - 0
package.json

@@ -28,6 +28,7 @@
     "echarts": "^5.5.1",
     "echarts-gl": "^2.0.9",
     "element-plus": "^2.8.6",
+    "jsencrypt": "^3.3.2",
     "mitt": "^3.0.1",
     "moment": "^2.30.1",
     "pinia": "^2.2.4",

+ 1 - 1
public/constant.json

@@ -1,3 +1,3 @@
 {
-  "TOKEN_CODE": "32f1bce6-7c24-44dc-81a3-f84982ffe6fa"
+  "TOKEN_CODE": "e7098fb9-6009-4221-8e4e-a4619cb367e0"
 }

+ 70 - 62
src/api/alarm.ts

@@ -1,68 +1,76 @@
+import request from '@/utils/request'
+
 /**
  * 水文测站实时信息
  */
-export function getAlarmInfo() {
-  // return request({
-  //   url: '/tbazmw_api/warnRecord/getPage',
-  //   method: 'get'
-  // })
-  return Promise.resolve([
-    {
-      "id": "1",
-      "warnType": "设备故障",
-      "warnContent": "COD分析仪故障",
-      "reportTime": "2024-10-30 14:00:00",
-    }, {
-      "id": "2",
-      "warnType": "数据中断",
-      "warnContent": "水质监测数据中断",
-      "reportTime": "2024-10-30 14:00:00",
-    }, {
-      "id": "3",
-      "warnType": "数据异常",
-      "warnContent": "数据出现大值",
-      "reportTime": "2024-10-30 14:00:00",
-    }, {
-      "id": "4",
-      "warnType": "设备故障",
-      "warnContent": "高锰酸盐设备故障",
-      "reportTime": "2024-10-30 14:00:00",
-    }, {
-      "id": "5",
-      "warnType": "设备不在线",
-      "warnContent": "设备断电",
-      "reportTime": "2024-10-30 14:00:00",
-    }, {
-      "id": "6",
-      "warnType": "温度",
-      "warnContent": "高温报警",
-      "reportTime": "2024-10-30 14:00:00",
-    }, {
-      "id": "7",
-      "warnType": "数据跳变",
-      "warnContent": "数据变化范围超10%",
-      "reportTime": "2024-10-30 14:00:00",
-    }, {
-      "id": "8",
-      "warnType": "水压",
-      "warnContent": "高压泵进口水压力低报警",
-      "reportTime": "2024-10-30 14:00:00",
-    }, {
-      "id": "9",
-      "warnType": "温度",
-      "warnContent": "高温报警",
-      "reportTime": "2024-10-30 14:00:00",
-    }, {
-      "id": "10",
-      "warnType": "数据跳变",
-      "warnContent": "数据变化范围超10%",
-      "reportTime": "2024-10-30 14:00:00",
-    }, {
-      "id": "11",
-      "warnType": "水压",
-      "warnContent": "高压泵进口水压力低报警",
-      "reportTime": "2024-10-30 14:00:00",
+
+export function getAlarmInfo(data) {
+  return request({
+    url: '/lantai_api/warnRecord/getPage',
+    method: 'get',
+    params:data,
+    headers: {
+      Authorization: localStorage.getItem('Authorization'),
     },
-  ])
+  })
+
+  // return Promise.resolve([
+  //   {
+  //     "id": "1",
+  //     "warnType": "设备故障",
+  //     "warnContent": "COD分析仪故障",
+  //     "reportTime": "2024-10-30 14:00:00",
+  //   }, {
+  //     "id": "2",
+  //     "warnType": "数据中断",
+  //     "warnContent": "水质监测数据中断",
+  //     "reportTime": "2024-10-30 14:00:00",
+  //   }, {
+  //     "id": "3",
+  //     "warnType": "数据异常",
+  //     "warnContent": "数据出现大值",
+  //     "reportTime": "2024-10-30 14:00:00",
+  //   }, {
+  //     "id": "4",
+  //     "warnType": "设备故障",
+  //     "warnContent": "高锰酸盐设备故障",
+  //     "reportTime": "2024-10-30 14:00:00",
+  //   }, {
+  //     "id": "5",
+  //     "warnType": "设备不在线",
+  //     "warnContent": "设备断电",
+  //     "reportTime": "2024-10-30 14:00:00",
+  //   }, {
+  //     "id": "6",
+  //     "warnType": "温度",
+  //     "warnContent": "高温报警",
+  //     "reportTime": "2024-10-30 14:00:00",
+  //   }, {
+  //     "id": "7",
+  //     "warnType": "数据跳变",
+  //     "warnContent": "数据变化范围超10%",
+  //     "reportTime": "2024-10-30 14:00:00",
+  //   }, {
+  //     "id": "8",
+  //     "warnType": "水压",
+  //     "warnContent": "高压泵进口水压力低报警",
+  //     "reportTime": "2024-10-30 14:00:00",
+  //   }, {
+  //     "id": "9",
+  //     "warnType": "温度",
+  //     "warnContent": "高温报警",
+  //     "reportTime": "2024-10-30 14:00:00",
+  //   }, {
+  //     "id": "10",
+  //     "warnType": "数据跳变",
+  //     "warnContent": "数据变化范围超10%",
+  //     "reportTime": "2024-10-30 14:00:00",
+  //   }, {
+  //     "id": "11",
+  //     "warnType": "水压",
+  //     "warnContent": "高压泵进口水压力低报警",
+  //     "reportTime": "2024-10-30 14:00:00",
+  //   },
+  // ])
 }
 

+ 72 - 0
src/api/device.ts

@@ -1,3 +1,5 @@
+import request from '@/utils/request'
+
 /**
  * 设备一览表
  */
@@ -149,3 +151,73 @@ export function getOperationsPersonnelData() {
     }
   ])
 }
+
+  export function getEquipmentData(data){
+  return request({
+    url: '/lantai_api/equipment/getPage',
+    method: 'get',
+    params:data,
+    headers: {
+      Authorization: localStorage.getItem('Authorization'),
+    },
+  })
+}
+
+export function getMaintenanceStatistics(data){
+  return request({
+    url: '/lantai_api/maintenanceStatistics/maintenanceStatistics',
+    method: 'get',
+    params:data,
+    headers: {
+      Authorization: localStorage.getItem('Authorization'),
+    },
+  })
+}
+
+export function getHistoryStationFailureCount(data){
+  return request({
+    url: '/lantai_api/maintenanceStatistics/getHistoryStationFailureCount',
+    method: 'get',
+    params:data,
+    headers: {
+      Authorization: localStorage.getItem('Authorization'),
+    },
+  })
+}
+
+// 设备运维记录最新一条
+export function getMaintenanceTaskLog(data){
+  return request({
+    url: '/lantai_api/maintenanceTaskLog/getPage',
+    method: 'get',
+    params:data,
+    headers: {
+      Authorization: localStorage.getItem('Authorization'),
+    },
+  })
+}
+
+// 设备运维任务
+export function getMaintenanceScheduleTask(data){
+  return request({
+    url: '/lantai_api/maintenanceTask/getPage',
+    method: 'get',
+    params:data,
+    headers: {
+      Authorization: localStorage.getItem('Authorization'),
+    },
+  })
+}
+
+// 配件运维信息
+export function getSparePart(data){
+  return request({
+    url: '/lantai_api/sparePart/getPage',
+    method: 'get',
+    params:data,
+    headers: {
+      Authorization: localStorage.getItem('Authorization'),
+    },
+  })
+}
+

+ 44 - 0
src/api/lantaiLogin.ts

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+import JsEncrypt from 'jsencrypt'
+
+// 登录按钮交互
+export function postUserInfo (loginName,password) {
+  // this.password = Encrypt(this.password)
+  getPublicKey({}).then(res => {
+    const publicKey = res.data.pukString
+    const prkKey = res.data.prkKey
+    const encrypt = new JsEncrypt()
+    encrypt.setPublicKey(publicKey) // 放置自己的公钥
+    const resPassword = encrypt.encrypt(password)
+    const resLoginName = encrypt.encrypt(loginName)
+    login({
+      loginName: resLoginName,
+      password: resPassword,
+      prkKey: prkKey,
+    }).then(res => {
+      if (res.status != 200) {
+        console.log(res.message)
+        return
+      }
+      localStorage.setItem('Authorization', res.data.toString())
+      return res.data.toString()
+    })
+  })
+}
+
+function login(data){
+  return request({
+    url: '/lantai_api/otherLogin',
+    method: 'post',
+    data:JSON.stringify(data),
+  })
+}
+
+
+function getPublicKey(){
+  return request({
+    url: '/lantai_api/getPublicKey',
+    method: 'get',
+  })
+}
+

+ 3 - 2
src/components/DeviceComponent/rainfall.vue

@@ -9,11 +9,12 @@ const route = useRoute()
 const chartRef = ref(null)
 
 async function reloadChart() {
-  const sevenDayAgo = new Date(new Date().getTime() - 7 * 24 * 60 * 60 * 1000)
+  const curDay = new Date(new Date().getTime() + 1 * 24 * 60 * 60 * 1000)
+  const sevenDayAgo = new Date(curDay.getTime() - 7 * 24 * 60 * 60 * 1000)
   const rainfallData = await getRainfallListOfPageByStcd({
     stcd: route.params.stcd,
     startTime: formatd(sevenDayAgo),
-    endTime: formatd(new Date())
+    endTime: formatd(curDay)
   }).then(res => {
     return res.rows
   })

+ 1 - 1
src/components/StripeTable.vue

@@ -19,7 +19,7 @@ function handleClick(row) {
         {{ scope.row[column.prop] }}
       </template>
       <template v-else #default="scope">
-        <span v-html="column.convertFn(scope.row[column.prop], scope.$index)"></span>
+        <span v-html="column.convertFn(scope.row[column.prop],scope.$index)"></span>
       </template>
     </el-table-column>
   </el-table>

+ 20 - 18
src/layout/index.vue

@@ -1,19 +1,20 @@
 <script lang="ts" setup>
-import {AppMain, Navbar} from '@/layout/components/index.js'
+import { AppMain, Navbar } from '@/layout/components/index.js'
 import AntvMap from '@/components/AntvMap/index.vue'
 import UePlayer from '@/components/UePlayer.vue'
-import {useAppStore} from '@/stores/app'
-import {computed, onMounted, reactive, ref, watch} from 'vue'
-import {useRoute} from 'vue-router'
-import {useStationStore} from '@/stores/station'
+import { useAppStore } from '@/stores/app'
+import { computed, onMounted, reactive, ref, watch } from 'vue'
+import { useRoute } from 'vue-router'
+import { useStationStore } from '@/stores/station'
 import bus from '@/utils/bus'
-import {getStation} from '@/utils/station'
-import {getAlarmData} from '@/api/rolldata'
-import {jumpPage} from '@/utils'
+import { getStation } from '@/utils/station'
+import { getAlarmData } from '@/api/rolldata'
+import { jumpPage } from '@/utils'
 import CrossSection from '@/components/CrossSection.vue'
-import {Vue3Marquee} from 'vue3-marquee'
-import X2js from 'x2js';
-import OpeningAnimation from "@/components/OpeningAnimation.vue";
+import { Vue3Marquee } from 'vue3-marquee'
+import X2js from 'x2js'
+import OpeningAnimation from '@/components/OpeningAnimation.vue'
+import { postUserInfo } from '@/api/lantaiLogin'
 
 const appStore = useAppStore()
 const stationStore = useStationStore()
@@ -24,7 +25,7 @@ const showOpeningAnimation = computed(() => route.path.indexOf('/index') > -1)
 const showOpeningAnimation2 = ref(true)
 let navbarHeight = '12vh'
 let theme = ''
-let navbarStyle = {height: navbarHeight}
+let navbarStyle = { height: navbarHeight }
 const dialog = reactive({
   visible: false,
   title: '断面',
@@ -78,22 +79,23 @@ bus.on('handle_ue_response', (data) => {
 async function getAlarmInfo() {
   alarmInfo.value = await getAlarmData().then(res => {
     // 实例化
-    let x2js = new X2js();
+    let x2js = new X2js()
 // 将xml解析为我们需要的json对象
-    let json = x2js.xml2js(res);
+    let json = x2js.xml2js(res)
     return json.DataTable.diffgram.DocumentElement.Table.things
   })
 }
 
 onMounted(() => {
   getAlarmInfo()
+  postUserInfo('jssytsq', 'Jshui@2024')
 })
 
 // 路由监听
 watch(() => route.path, path => {
   // 首页展示动画
-  showOpeningAnimation2.value = path.indexOf('/index') > -1;
-}, {deep: true})
+  showOpeningAnimation2.value = path.indexOf('/index') > -1
+}, { deep: true })
 </script>
 
 <template>
@@ -128,9 +130,9 @@ watch(() => route.path, path => {
         <div class="alarm-info" v-html="alarmInfo"></div>
       </Vue3Marquee>
       <!-- 顶部 -->
-      <navbar :style="navbarStyle"/>
+      <navbar :style="navbarStyle" />
       <!-- 展示页 -->
-      <app-main/>
+      <app-main />
 
       <el-dialog v-model="dialog.visible" :modal="false" :title="dialog.title" align-center draggable>
         <cross-section v-if="dialog.visible"></cross-section>

+ 1 - 0
src/utils/env.ts

@@ -1,3 +1,4 @@
+
 /**
  * 获取静态配置数据
  */

+ 1 - 0
src/utils/request.ts

@@ -19,6 +19,7 @@ service.interceptors.request.use(
       !config.url.startsWith("/tbazmw_api") &&
       !config.url.startsWith("/gx_api") &&
       !config.url.startsWith("/gx_gj_api") &&
+      !config.url.startsWith("/lantai_api") &&
       !config.url.startsWith("/nmc_api") &&
       !config.url.startsWith("/video_api") &&
       !validURL(config.url)

+ 131 - 63
src/views/Device.vue

@@ -1,20 +1,22 @@
 <script lang="ts" setup>
-import {computed, onMounted, onUnmounted, ref} from 'vue'
-import {useRoute} from 'vue-router'
+import { computed, onMounted, onUnmounted, ref } from 'vue'
+import { useRoute } from 'vue-router'
 import RightFrame from '@/components/RightFrame.vue'
 import Card01 from '@/components/card/Card01.vue'
 import StripeTable from '@/components/StripeTable.vue'
-import {getDeviceByName, getDeviceTypeByName} from '@/utils/device'
+import { getDeviceByName, getDeviceTypeByName } from '@/utils/device'
 import Chart from '@/components/Chart.vue'
 import StationRightButtonGroup from '@/components/StationRightButtonGroup.vue'
-import {Label, View} from "@/utils/tdInstruction";
-import GwVideo from "@/components/Video/index.vue";
-import {getVideoCodeByMark} from "@/components/Video/video";
-import WaterQualityAnalysis from "@/components/DeviceComponent/WaterQualityAnalysis.vue";
-import WaterLevel from "@/components/DeviceComponent/WaterLevel.vue";
-import Rainfall from "@/components/DeviceComponent/Rainfall.vue";
-import AdcpFlow from "@/components/DeviceComponent/AdcpFlow.vue";
-import WaterFlow from "@/components/DeviceComponent/WaterFlow.vue";
+import { Label, View } from '@/utils/tdInstruction'
+import GwVideo from '@/components/Video/index.vue'
+import { getVideoCodeByMark } from '@/components/Video/video'
+import WaterQualityAnalysis from '@/components/DeviceComponent/WaterQualityAnalysis.vue'
+import WaterLevel from '@/components/DeviceComponent/WaterLevel.vue'
+import Rainfall from '@/components/DeviceComponent/Rainfall.vue'
+import AdcpFlow from '@/components/DeviceComponent/AdcpFlow.vue'
+import WaterFlow from '@/components/DeviceComponent/WaterFlow.vue'
+import { getMaintenanceScheduleTask, getMaintenanceTaskLog, getSparePart } from '@/api/device'
+import moment from 'moment'
 
 const route = useRoute()
 const right3Ref = ref(null)
@@ -25,43 +27,54 @@ const deviceDetail = computed(() => device && device.detail ? device.detail.spli
 // 视频图片
 const videoImageSrc = new URL('@/assets/images/tmp/jiankong.png', import.meta.url).href
 // 获取视频CODE
-const videoCode = ref(getVideoCodeByMark(route.params.stcd + '', "室外"))
+const videoCode = ref(getVideoCodeByMark(route.params.stcd + '', '室外'))
 
 
 const deviceStatusColumns = [
-  {label: '维护信息', prop: 'deviceName', width: '100'},
-  {label: '维护人员', prop: 'woker', width: '90'},
-  {label: '维护日期‌', prop: 'updateTm'},
-  {label: '状态', prop: 'status', width: '70'}
+  { label: '维护信息', prop: 'deviceName', width: '100' },
+  { label: '维护人员', prop: 'woker', width: '90' },
+  { label: '维护日期‌', prop: 'updateTm' },
+  { label: '状态', prop: 'status', width: '70' }
 ]
+// const deviceStatusData = ref([])
 const deviceStatusData = [
-  {deviceName: '总磷分析仪', woker: '陈标', updateTm: '11-20 15:00:00', status: '正常'},
-  {deviceName: '总氮分析仪', woker: '于奇', updateTm: '11-20 15:00:00', status: '正常'},
-  {deviceName: '水位计', woker: '张孝荣', updateTm: '11-20 15:00:00', status: '正常'},
-  {deviceName: '氨氮分析仪', woker: '张孝荣', updateTm: '11-20 15:00:00', status: '正常'}
+  { deviceName: '总磷分析仪', woker: '陈标', updateTm: '11-20 15:00:00', status: '正常' },
+  { deviceName: '总氮分析仪', woker: '于奇', updateTm: '11-20 15:00:00', status: '正常' },
+  { deviceName: '水位计', woker: '张孝荣', updateTm: '11-20 15:00:00', status: '正常' },
+  { deviceName: '氨氮分析仪', woker: '张孝荣', updateTm: '11-20 15:00:00', status: '正常' }
 ]
 const accessoriesColumns = [
-  {label: '耗材名称', prop: 'name', width: '110'},
-  {label: '剩余有效期', prop: 'days', width: '110'},
-  {label: '到期时间', prop: 'updateTm'}
-]
-const accessoriesData = [
-  {name: '1-16泵管', days: 120, updateTm: '11-20 15:00:00'},
-  {name: '试管', days: 20, updateTm: '11-20 15:00:00'},
-  {name: '滴定管', days: 90, updateTm: '11-20 15:00:00'},
-  {name: '3-16泵管', days: 65, updateTm: '11-20 15:00:00'},
-  {name: '瓶子', days: 102, updateTm: '11-20 15:00:00'}
+  { label: '耗材名称', prop: 'partName', width: '110' },
+  {
+    label: '剩余有效期', prop: 'warranty', width: '110', convertFn: (data) => {
+      var formatDate = 'yyyy-MM-DD'
+      var curday = moment().format(formatDate)
+      var outday = moment(data)
+      return outday.diff(curday, 'days')
+    }
+  },
+  {
+    label: '到期时间', prop: 'warranty'
+  }
 ]
+const accessoriesData=ref([])
+// const accessoriesData = [
+//   { name: '1-16泵管', days: 120, warranty: '2025-11-20' }
+//   // { name: '试管', days: 20, warranty: '11-20 15:00:00' },
+//   // { name: '滴定管', days: 90, warranty: '11-20 15:00:00' },
+//   // { name: '3-16泵管', days: 65, warranty: '11-20 15:00:00' },
+//   // { name: '瓶子', days: 102, warranty: '11-20 15:00:00' }
+// ]
 const reagentColumns = [
-  {label: '试剂名称', prop: 'name'},
-  {label: '添加体积', prop: 'volume', width: '110'},
-  {label: '更换时间', prop: 'updateTm', width: '110'}
+  { label: '试剂名称', prop: 'name' },
+  { label: '添加体积', prop: 'volume', width: '110' },
+  { label: '更换时间', prop: 'updateTm', width: '110' }
 ]
 const reagentData = [
-  {name: '硫酸溶液', volume: 2, updateTm: '11-20 15:00:00'},
-  {name: '高锰酸钾溶液', volume: 1, updateTm: '11-20 15:00:00'},
-  {name: '草酸钠溶液', volume: 3, updateTm: '11-20 15:00:00'},
-  {name: '去离子水', volume: 2, updateTm: '11-20 15:00:00'}
+  { name: '硫酸溶液', volume: 2, updateTm: '11-20 15:00:00' },
+  { name: '高锰酸钾溶液', volume: 1, updateTm: '11-20 15:00:00' },
+  { name: '草酸钠溶液', volume: 3, updateTm: '11-20 15:00:00' },
+  { name: '去离子水', volume: 2, updateTm: '11-20 15:00:00' }
 ]
 // function reloadRight3(list) {
 //   if (!list || list.length === 0) {
@@ -175,7 +188,7 @@ const reagentData = [
 //   }
 //   right3Ref.value.loadChart(option)
 // }
-function reloadRight3() {
+async function reloadRight3() {
   const option = {
     // backgroundColor: "#0B2D55",
     tooltip: {
@@ -201,8 +214,8 @@ function reloadRight3() {
       axisLabel: { // 坐标轴刻度标签的相关设置
         color: '#02cacf'
       },
-      axisTick: {show: false},
-      data: ['1-16氯管', 'p3-16氯管', '3-16氯管']
+      axisTick: { show: false },
+      data: sparePart.value["xdata"]
     }],
     yAxis: [{
       name: '个',
@@ -229,7 +242,7 @@ function reloadRight3() {
       name: '数量',
       type: 'bar',
       itemStyle: {
-        color: function (params) {
+        color: function(params) {
           // 根据params的
           const colorsMap = [
             '#4768ec',
@@ -245,25 +258,86 @@ function reloadRight3() {
         show: true,
         position: 'top'
       },
-      data: [3, 5, 6]
+      data: sparePart.value["ydata"]
     }
     ]
   }
   right3Ref.value.loadChart(option)
 }
 
+const maintainRecord = ref({})
+
+// 设备运维记录
+function getMaintainRecordData() {
+  var data = {
+    'page': 1,
+    'pageSize': 1,
+    'stationCode': route.params.stcd,
+    'equipmentName': route.params.equipmentName ? route.params.equipmentName : ''
+  }
+  getMaintenanceTaskLog(data).then(res => {
+    if (res.status == 200) {
+      if (res.data.length != 0) {
+        maintainRecord.value = res.data.records[0]
+      }
+    }
+  })
+}
+
+// 设备维护任务(接口有问题)
+function getMaintainTaskData() {
+  var data = {
+    'page': 1,
+    'pageSize': 1,
+    'stationCode': route.params.stcd,
+    'equipmentName': route.params.equipmentName ? route.params.equipmentName : ''
+  }
+  getMaintenanceScheduleTask(data).then(res => {
+    if (res.status == 200) {
+      if (res.data.length != 0) {
+        // deviceStatusData.value = res.data.records
+      }
+    }
+  })
+}
+const sparePart = ref({})
+// 配件运维信息(需要提供测站id和设备id)
+function getSparePartData() {
+  var data = {
+    'page': 1,
+    'pageSize': 1
+  }
+  getSparePart(data).then(res => {
+    if (res.status == 200) {
+      if (res.data.length != 0) {
+        accessoriesData.value = res.data.records
+      }
+    }
+    var xdata=[]
+    var ydata=[]
+    accessoriesData.value.forEach(d=>{
+      xdata.push(d["partName"])
+      ydata.push(d["partTotal"])
+    })
+    sparePart.value["xdata"]=xdata
+    sparePart.value["ydata"]=ydata
+    reloadRight3()
+
+  })
+}
+
 onMounted(() => {
-  // reloadRight3([])
-  // reloadRight3()
+  getMaintainRecordData()
+  getMaintainTaskData()
+  getSparePartData()
 })
-
 onUnmounted(() => {
   // 关闭水质仪器视角
   if (deviceType.value === 'waterQuality') {
     View.closeDeviceView(route.params.stcd)
   }
   // 关闭 adcp 特效与弹窗
-  if (device.value.ueDeviceName === "H-ADCP") {
+  if (device.value.ueDeviceName === 'H-ADCP') {
     Label.setStationLabel(route.params.stcd, 'ADCP弹框', false)
     Label.adcpfx(route.params.stcd, false)
   }
@@ -281,15 +355,13 @@ onUnmounted(() => {
               <p v-for="text in deviceDetail" class="introduce-text" v-html="text"></p>
             </el-col>
             <el-col :span="8">
-              <img v-if="device.img" :src="device.img" alt="" class="introduce-float-img"/>
+              <img v-if="device.img" :src="device.img" alt="" class="introduce-float-img" />
             </el-col>
           </el-row>
           <h4 style="color: #00ccff">维护记录</h4>
-          <p>维护日期‌:2024年11月20日</p>
+          <p>维护日期‌:{{ maintainRecord.handleTime }}</p>
           <p>维护内容:</p>
-          <p>·清洗采样过滤头及管路,检查位置确保采样顺利。</p>
-          <p>·检查电源线路,确保干燥和稳定。</p>
-          <p>·校准仪器,确保测量准确性。</p>
+          <p>{{ maintainRecord.warnContent }}</p>
         </card01>
         <card01 style="height: 40%" title="设备维护情况">
           <stripe-table :columns="deviceStatusColumns" :data="deviceStatusData"></stripe-table>
@@ -303,15 +375,13 @@ onUnmounted(() => {
               <p v-for="text in deviceDetail" class="introduce-text" v-html="text"></p>
             </el-col>
             <el-col :span="8">
-              <img v-if="device.img" :src="device.img" alt="" class="introduce-float-img"/>
+              <img v-if="device.img" :src="device.img" alt="" class="introduce-float-img" />
             </el-col>
           </el-row>
           <h4 style="color: #00ccff">维护记录</h4>
-          <p>维护日期‌:2024年11月20日</p>
+          <p>维护日期‌:{{ maintainRecord.handleTime }}</p>
           <p>维护内容:</p>
-          <p>·清洗采样过滤头及管路,检查位置确保采样顺利。</p>
-          <p>·检查电源线路,确保干燥和稳定。</p>
-          <p>·校准仪器,确保测量准确性。</p>
+          <p>{{ maintainRecord.warnContent }}</p>
         </card01>
         <card01 style="height: 40%" title="水质监测">
           <water-quality-analysis></water-quality-analysis>
@@ -327,15 +397,13 @@ onUnmounted(() => {
               <p v-for="text in deviceDetail" class="introduce-text" v-html="text"></p>
             </el-col>
             <el-col :span="8">
-              <img v-if="device.img" :src="device.img" alt="" class="introduce-float-img"/>
+              <img v-if="device.img" :src="device.img" alt="" class="introduce-float-img" />
             </el-col>
           </el-row>
           <h4 style="color: #00ccff">维护记录</h4>
-          <p>维护日期‌:2024年11月20日</p>
+          <p>维护日期‌:{{ maintainRecord.handleTime }}</p>
           <p>维护内容:</p>
-          <p>·清洗采样过滤头及管路,检查位置确保采样顺利。</p>
-          <p>·检查电源线路,确保干燥和稳定。</p>
-          <p>·校准仪器,确保测量准确性。</p>
+          <p>{{ maintainRecord.warnContent }}</p>
         </card01>
         <card01 style="height: 40%" title="设备维护情况">
           <stripe-table :columns="deviceStatusColumns" :data="deviceStatusData"></stripe-table>
@@ -358,8 +426,8 @@ onUnmounted(() => {
       </template>
       <template v-if="deviceType=== 'flow'">
         <card01 style="height: 36%" title="流量监测">
-          <adcp-flow v-if="device.ueDeviceName === '无人船'"/>
-          <water-flow v-else/>
+          <adcp-flow v-if="device.ueDeviceName === '无人船'" />
+          <water-flow v-else />
         </card01>
       </template>
       <template v-if="deviceType=== 'waterQuality'">

+ 129 - 33
src/views/IntellOper.vue

@@ -1,65 +1,138 @@
 <script lang="ts" setup>
-import {onMounted, reactive, ref} from 'vue'
-import {useRoute} from 'vue-router'
+import { onMounted, reactive, ref } from 'vue'
+import { useRoute } from 'vue-router'
 import RightFrame from '@/components/RightFrame.vue'
 import Card01 from '@/components/card/Card01.vue'
 import StripeTable from '@/components/StripeTable.vue'
 import ColorTag from '@/components/tag/ColorTag.vue'
-import {getDeviceInfo, getOperationsPersonnelData} from '@/api/device'
+import { getDeviceInfo, getEquipmentData, getOperationsPersonnelData } from '@/api/device'
 import Chart from '@/components/Chart.vue'
-import {getPie3DSimple} from "@/utils/chart";
-import {View} from "@/utils/tdInstruction";
-import StationRightButtonGroup from "@/components/StationRightButtonGroup.vue";
-import {getDeviceByName} from "@/utils/device";
-import {getAlarmInfo} from '@/api/alarm'
+import { getPie3DSimple } from '@/utils/chart'
+import { View } from '@/utils/tdInstruction'
+import StationRightButtonGroup from '@/components/StationRightButtonGroup.vue'
+import { getDeviceByName } from '@/utils/device'
+import { getAlarmInfo } from '@/api/alarm'
+import { getMaintenanceStatistics, getHistoryStationFailureCount } from '@/api/device'
+import moment from 'moment'
 
 const route = useRoute()
 
 const color = ['#005aff', '#f8b551']
 const equipmentStatusData = reactive({
-  total: 10,
-  onlineTotal: 8,
+  total: 0,
+  onlineTotal: 0,
   '缺数': 0,
-  '上下限异常': 1,
+  '上下限异常': 0,
   '数据中断': 0,
-  '其他': 1
+  '临近质保期': 0
 })
 const operationsPersonnelColumns = [
-  {label: '姓名', prop: 'name'},
-  {label: '已处理', prop: 'processed', width: '100'},
-  {label: '未处理', prop: 'untreated', width: '100'}
+  { label: '姓名', prop: 'name' },
+  { label: '已处理', prop: 'processed', width: '100' },
+  { label: '未处理', prop: 'untreated', width: '100' }
 ]
 const operationsPersonnelData = reactive([])
 const deviceColumns = [
-  {label: '设备类型', prop: 'deviceType', width: '110'},
-  {label: '设备名称', prop: 'deviceName'},
-  {label: '运行状态', prop: 'state', width: '90'}
+  { label: '设备类型', prop: 'deviceType', width: '110' },
+  { label: '设备名称', prop: 'deviceName' },
+  { label: '运行状态', prop: 'state', width: '90' }
 ]
 const deviceData = reactive([])
 
+const alarmType = ref({
+  '1': '巡检维护',
+  '2': '故障',
+  '3': '仪器校准',
+  '4': '提醒'
+})
 
 const alarmColumns = [
   {
-    label: '报警类型', prop: 'warnType', width: '100', convertFn: (data) => {
+    label: '报警类型', prop: 'warnType', width: '80', convertFn: (data) => {
+      return data ? alarmType.value[data.trim()] : ''
+    }
+  },
+  {
+    label: '设备名称', prop: 'equipmentName', width: '120', convertFn: (data) => {
       return data ? data.trim() : ''
     }
   },
   {
-    label: '时间', prop: 'reportTime', convertFn: (data) => {
+    label: '时间', prop: 'reportTime', width: '60', convertFn: (data) => {
       return data ? data.substring(5, 16) : ''
     }
   },
   {
-    label: '告警内容', prop: 'warnContent', width: '180', convertFn: (data) => {
+    label: '告警内容', prop: 'warnContent', convertFn: (data) => {
       return data ? data.trim() : ''
     }
-  },
+  }
 ]
 const alarmData = reactive([])
 
+const maintenanceStatisticsData = reactive({
+  '1': 0,
+  '2': 0,
+  '3': 0,
+  '4': 0
+})
+
+async function getMaintenanceStatisticsData() {
+  var formatDate = 'yyyy-MM-DD'
+  var startTime = moment().format(formatDate)
+  var endTime = moment().add(1, 'days').format(formatDate)
+  await getMaintenanceStatistics({
+    'startTime': startTime,
+    'endTime': endTime,
+    'stcd': route.params.stcd
+  }).then(res => {
+    if (res.status == 200) {
+      if (res.data.length != 0) {
+//1 故障数量,2 提醒数量,3 巡检数量,4 定时巡检数量
+        console.log(res.data[0]['reportTime'])
+        maintenanceStatisticsData['1'] = parseInt(res.data[0]['1'])
+        maintenanceStatisticsData['2'] = parseInt(res.data[0]['2'])
+        maintenanceStatisticsData['3'] = parseInt(res.data[0]['3'])
+        maintenanceStatisticsData['4'] = parseInt(res.data[0]['4'])
+      }
+    }
+  })
+  reloadRight3()
+}
+
+function getStationFailureCount() {
+  var formatDate = 'yyyy-MM-DD'
+  var startTime = moment().format(formatDate)
+  var endTime = moment().add(1, 'days').format(formatDate)
+  getHistoryStationFailureCount({
+    'startTime': startTime,
+    'endTime': endTime,
+    'stcd': route.params.stcd
+  }).then(res => {
+    if (res.status == 200) {
+      if (res.data.length != 0) {
+        //sjzdNum 数据中断,ccsxNum 超出上限,ljzbqNum 临近质保期,qsNum 缺数,ccxxNum 超出下限
+        console.log(res.data[0]['reportTime'])
+        equipmentStatusData['缺数'] = parseInt(res.data[0]['qsNum'])
+        equipmentStatusData['上下限异常'] = parseInt(res.data[0]['ccsxNum']) + parseInt(res.data[0]['ccxxNum'])
+        equipmentStatusData['数据中断'] = parseInt(res.data[0]['sjzdNum'])
+        equipmentStatusData['临近质保期'] = parseInt(res.data[0]['ljzbqNum'])
+      }
+    }
+  })
+  reloadRight3()
+}
+
 function getAlarmList() {
-  getAlarmInfo().then(res => {
-    alarmData.push(...res)
+  var data = {
+    'page': 1,
+    'pageSize': 200,
+    'stationCode': route.params.stcd
+  }
+  getAlarmInfo(data).then(res => {
+    if (res.status == 200) {
+      alarmData.push(...res.data.records)
+    }
     // initPoints()
   })
 }
@@ -70,28 +143,28 @@ function reloadRight3() {
   const optionData = [
     {
       name: '故障',
-      value: 1,
+      value: maintenanceStatisticsData['1'],
       itemStyle: {
         color: '#f3914b'
       }
     },
     {
       name: '提醒',
-      value: 4,
+      value: maintenanceStatisticsData['2'],
       itemStyle: {
         color: '#f5bf53'
       }
     },
     {
       name: '巡检',
-      value: 6,
+      value: maintenanceStatisticsData['3'],
       itemStyle: {
         color: '#92d1f4'
       }
     },
     {
       name: '定时巡检',
-      value: 3,
+      value: maintenanceStatisticsData['4'],
       itemStyle: {
         color: '#0e2d5b'
       }
@@ -135,6 +208,26 @@ function getDeviceInfoList() {
   })
 }
 
+function getEquipmentList() {
+  var data={
+    "page":1,
+    "pageSize":1000,
+    "stationCode":route.params.stcd
+  }
+  getEquipmentData(data).then(res => {
+    if (res.status == 200) {
+      equipmentStatusData.total = res.data.records.length
+      var num=0
+      res.data.records.forEach(d => {
+        if (d.status != null) {
+          num++
+        }
+      })
+      equipmentStatusData.onlineTotal = num
+    }
+  })
+}
+
 function getDeviceDetailInfoList() {
   getOperationsPersonnelData().then(res => {
     operationsPersonnelData.push(...res)
@@ -147,13 +240,15 @@ onMounted(() => {
   getDeviceInfoList()
   getDeviceDetailInfoList()
   getAlarmList()
-  reloadRight3()
+  getMaintenanceStatisticsData()//右1 维护信息统计
+  getStationFailureCount()//左1 异常数据统计
+  getEquipmentList()//统计
 })
 
 function handleDeviceClick(row) {
-  const device = getDeviceByName(row.deviceName, 'deviceName');
+  const device = getDeviceByName(row.deviceName, 'deviceName')
   if (device) {
-    if (device["deviceType"] === "水质测验设备") {
+    if (device['deviceType'] === '水质测验设备') {
       View.changeDeviceView('打开模型', route.params.stcd, device.ueDeviceName)
     } else {
       View.changeView(`${route.params.stcd}_${device.ueDeviceName}`)
@@ -176,7 +271,7 @@ function handleDeviceClick(row) {
           <el-col :span="10">
             <div style="display: flex;justify-content: center;">
               <!--              <div style="position: absolute;bottom:40%;font-size:16px;">设备清单</div>-->
-              <img :src="imgSrc" style="height: 120px;"/>
+              <img :src="imgSrc" style="height: 120px;" />
             </div>
           </el-col>
           <el-col :span="7">
@@ -201,7 +296,8 @@ function handleDeviceClick(row) {
             <color-tag :value="equipmentStatusData['数据中断']" background-color="#97759c" label="数据中断"></color-tag>
           </el-col>
           <el-col :span="6" style="height: 100%;">
-            <color-tag :value="equipmentStatusData['其他']" backgroundColor="#adcbe0" label="其他"></color-tag>
+            <color-tag :value="equipmentStatusData['临近质保期']" backgroundColor="#adcbe0"
+                       label="临近质保期"></color-tag>
           </el-col>
         </el-row>
       </card01>

+ 22 - 20
src/views/Situational.vue

@@ -205,11 +205,13 @@ async function reloadLeft3() {
 }
 
 async function reloadRight1() {
+  debugger
+  const curDay = new Date(new Date().getTime() + 1 * 24 * 60 * 60 * 1000)
   const sevenDayAgo = new Date(new Date().getTime() - 7 * 24 * 60 * 60 * 1000)
   const rainfallData = await getRainfallListOfPageByStcd({
     stcd: route.params.stcd,
     startTime: formatd(sevenDayAgo),
-    endTime: formatd(new Date())
+    endTime: formatd(curDay)
   }).then(res => {
     return res.rows
   })
@@ -450,11 +452,11 @@ onMounted(() => {
         </el-row>
       </card01>
       <card01 style="height: 33%" title="流量监测">
-        <template v-slot:sec_header>
-          <span
-            style="font-size: 12px;display: inline-block;float:right;margin-right: 50px;cursor: pointer;"
-            @click="jumpTo('flow')">更多>></span>
-        </template>
+<!--        <template v-slot:sec_header>-->
+<!--          <span-->
+<!--            style="font-size: 12px;display: inline-block;float:right;margin-right: 50px;cursor: pointer;"-->
+<!--            @click="jumpTo('flow')">更多>></span>-->
+<!--        </template>-->
         <chart ref="left2Ref"></chart>
       </card01>
       <card01 style="height: 33%">
@@ -462,21 +464,21 @@ onMounted(() => {
           <span class="title">水情分析</span>
           <span style="font-size: 0.8rem;">&nbsp;&nbsp;江南大运河沿线</span>
         </template>
-        <template v-slot:sec_header>
-          <span
-            style="font-size: 12px;display: inline-block;float:right;margin-right: 50px;cursor: pointer;"
-            @click="jumpTo('sw')">更多>></span>
-        </template>
+<!--        <template v-slot:sec_header>-->
+<!--          <span-->
+<!--            style="font-size: 12px;display: inline-block;float:right;margin-right: 50px;cursor: pointer;"-->
+<!--            @click="jumpTo('sw')">更多>></span>-->
+<!--        </template>-->
         <chart ref="left3Ref"></chart>
       </card01>
     </template>
     <template #rightModule>
       <card01 style="height: 31%" title="雨量监测">
-        <template v-slot:sec_header>
-          <span
-            style="font-size: 12px;display: inline-block;float:right;margin-right: 50px;cursor: pointer;"
-            @click="jumpTo('yl')">更多>></span>
-        </template>
+<!--        <template v-slot:sec_header>-->
+<!--          <span-->
+<!--            style="font-size: 12px;display: inline-block;float:right;margin-right: 50px;cursor: pointer;"-->
+<!--            @click="jumpTo('yl')">更多>></span>-->
+<!--        </template>-->
         <chart ref="right1Ref"></chart>
       </card01>
       <card01 style="height: 38%" title="水质评价">
@@ -487,10 +489,10 @@ onMounted(() => {
           <span class="title">水质分析</span>
           <span style="font-size: 0.8rem;">&nbsp;&nbsp;江南大运河沿线</span>
         </template>
-        <template v-slot:sec_header>
-          <span style="font-size: 12px;display: inline-block;float:right;margin-right: 50px;cursor: pointer;"
-                @click="jumpTo('sz')">更多>></span>
-        </template>
+<!--        <template v-slot:sec_header>-->
+<!--          <span style="font-size: 12px;display: inline-block;float:right;margin-right: 50px;cursor: pointer;"-->
+<!--                @click="jumpTo('sz')">更多>></span>-->
+<!--        </template>-->
         <chart ref="right3Ref"></chart>
       </card01>
     </template>

+ 17 - 3
src/views/StationHouse.vue

@@ -113,10 +113,17 @@ function getLatestWaterQuality() {
   })
 }
 
+const alarmType = ref({
+  '1': '巡检维护',
+  '2': '故障',
+  '3': '仪器校准',
+  '4': '提醒'
+})
+
 const alarmColumns = [
   {
     label: '报警类型', prop: 'warnType', width: '100', convertFn: (data) => {
-      return data ? data.trim() : ''
+      return data ? alarmType.value[data.trim()] : ''
     }
   },
   {
@@ -134,8 +141,15 @@ const alarmData = reactive([])
 const left1Ref = ref(null)
 
 function getAlarmList() {
-  getAlarmInfo().then(res => {
-    alarmData.push(...res)
+  var data = {
+    'page': 1,
+    'pageSize': 200,
+    'stationCode': route.params.stcd
+  }
+  getAlarmInfo(data).then(res => {
+    if (res.status == 200) {
+      alarmData.push(...res.data.records)
+    }
     // initPoints()
   })
 }

+ 6 - 5
src/views/Zhyw.vue

@@ -1,7 +1,6 @@
 <script lang="ts" setup>
-import {onMounted, ref} from 'vue'
-import {useRoute} from 'vue-router'
-import {getFetchEnv} from "@/utils/env";
+import { onMounted, ref } from 'vue'
+import { useRoute } from 'vue-router'
 
 // const imgSrc = ref(null)
 const route = useRoute()
@@ -18,8 +17,10 @@ const urlMap = {
 onMounted(async () => {
   const stcd = route.params.stcd
   const srcType = route.params.type
-  const env = await getFetchEnv()
-  iframeUrl.value = `${urlMap[srcType]}?code=${env['TOKEN_CODE']}&stcd=${stcd}`
+
+  const token = localStorage.getItem('Authorization')
+  debugger
+  iframeUrl.value = `${urlMap[srcType]}?code=${token}&stcd=${stcd}`
 })
 </script>