Device.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. <script lang="ts" setup>
  2. import {computed, onMounted, onUnmounted, ref} from 'vue'
  3. import {useRoute} from 'vue-router'
  4. import RightFrame from '@/components/RightFrame.vue'
  5. import Card01 from '@/components/card/Card01.vue'
  6. import StripeTable from '@/components/StripeTable.vue'
  7. import {getDeviceByName, getDeviceTypeByName} from '@/utils/device'
  8. import Chart from '@/components/Chart.vue'
  9. import StationRightButtonGroup from '@/components/StationRightButtonGroup.vue'
  10. import {Label, View} from "@/utils/tdInstruction";
  11. import GwVideo from "@/components/Video/index.vue";
  12. import {getVideoCodeByMark} from "@/components/Video/video";
  13. import WaterQualityAnalysis from "@/components/DeviceComponent/WaterQualityAnalysis.vue";
  14. import WaterLevel from "@/components/DeviceComponent/WaterLevel.vue";
  15. import Rainfall from "@/components/DeviceComponent/Rainfall.vue";
  16. import AdcpFlow from "@/components/DeviceComponent/AdcpFlow.vue";
  17. const route = useRoute()
  18. const right3Ref = ref(null)
  19. const device = ref(getDeviceByName(route.params.deviceid) || {})
  20. // 根据仪器类型展示信息 video、waterLevel、flow、rainfall、waterQuality、default
  21. const deviceType = computed(() => getDeviceTypeByName(route.params.deviceid))
  22. const deviceDetail = computed(() => device && device.detail ? device.detail.split('\n') : [])
  23. // 视频图片
  24. const videoImageSrc = new URL('@/assets/images/tmp/jiankong.png', import.meta.url).href
  25. // 获取视频CODE
  26. const videoCode = ref(getVideoCodeByMark(route.params.stcd + '', "室外"))
  27. const deviceStatusColumns = [
  28. {label: '维护信息', prop: 'deviceName', width: '100'},
  29. {label: '维护人员', prop: 'woker', width: '90'},
  30. {label: '维护日期‌', prop: 'updateTm'},
  31. {label: '状态', prop: 'status', width: '70'}
  32. ]
  33. const deviceStatusData = [
  34. {deviceName: '总磷分析仪', woker: '陈标', updateTm: '11-20 15:00:00', status: '正常'},
  35. {deviceName: '总氮分析仪', woker: '于奇', updateTm: '11-20 15:00:00', status: '正常'},
  36. {deviceName: '水位计', woker: '张孝荣', updateTm: '11-20 15:00:00', status: '正常'},
  37. {deviceName: '氨氮分析仪', woker: '张孝荣', updateTm: '11-20 15:00:00', status: '正常'}
  38. ]
  39. const accessoriesColumns = [
  40. {label: '耗材名称', prop: 'name', width: '110'},
  41. {label: '剩余有效期', prop: 'days', width: '110'},
  42. {label: '到期时间', prop: 'updateTm'}
  43. ]
  44. const accessoriesData = [
  45. {name: '1-16泵管', days: 120, updateTm: '11-20 15:00:00'},
  46. {name: '试管', days: 20, updateTm: '11-20 15:00:00'},
  47. {name: '滴定管', days: 90, updateTm: '11-20 15:00:00'},
  48. {name: '3-16泵管', days: 65, updateTm: '11-20 15:00:00'},
  49. {name: '瓶子', days: 102, updateTm: '11-20 15:00:00'}
  50. ]
  51. const reagentColumns = [
  52. {label: '试剂名称', prop: 'name'},
  53. {label: '添加体积', prop: 'volume', width: '110'},
  54. {label: '更换时间', prop: 'updateTm', width: '110'}
  55. ]
  56. const reagentData = [
  57. {name: '硫酸溶液', volume: 2, updateTm: '11-20 15:00:00'},
  58. {name: '高锰酸钾溶液', volume: 1, updateTm: '11-20 15:00:00'},
  59. {name: '草酸钠溶液', volume: 3, updateTm: '11-20 15:00:00'},
  60. {name: '去离子水', volume: 2, updateTm: '11-20 15:00:00'}
  61. ]
  62. // function reloadRight3(list) {
  63. // if (!list || list.length === 0) {
  64. // return
  65. // }
  66. //
  67. // const typeSet = new Set()
  68. // const times = []
  69. // list.forEach((item, index) => {
  70. // Object.keys(item).forEach(key => typeSet.add(key))
  71. // times.push(item['maintainDate'] || index + 1)
  72. // })
  73. // typeSet.delete('maintainDate')
  74. // const types = Array.from(typeSet)
  75. // const rawData = []
  76. // types.forEach(t => {
  77. // let array = []
  78. // list.forEach(d => array.push(d[t] || 0))
  79. // rawData.push(array)
  80. // })
  81. // const totalData = []
  82. // for (let i = 0; i < rawData[0].length; ++i) {
  83. // let sum = 0
  84. // for (let j = 0; j < rawData.length; ++j) {
  85. // sum += Number(rawData[j][i])
  86. // }
  87. // totalData.push(sum)
  88. // }
  89. // const grid = {
  90. // left: 10,
  91. // right: 10,
  92. // top: 50,
  93. // bottom: 10,
  94. // containLabel: true
  95. // }
  96. // const series = types.map((name, sid) => {
  97. // return {
  98. // name,
  99. // type: 'bar',
  100. // stack: 'total',
  101. // barWidth: '60%',
  102. // label: { show: false },
  103. // data: rawData[sid]
  104. // }
  105. // })
  106. // series.push({
  107. // name: '总计',
  108. // type: 'bar',
  109. // stack: 'total',
  110. // label: {
  111. // show: true,
  112. // position: 'top',
  113. // color: '#fff',
  114. // formatter: params => totalData[params.dataIndex] + '个'
  115. // },
  116. // data: totalData.map(t => 0)
  117. // })
  118. // let maxValue = totalData.reduce((a, b) => Math.max(a, b))
  119. // const option = {
  120. // tooltip: {
  121. // trigger: 'axis',
  122. // axisPointer: {
  123. // type: 'shadow'
  124. // },
  125. // formatter(params) {
  126. // let circle = `<span style="display:inline-block;margin-right:5px;border-radius:50%;width:10px;height:10px;left:5px;background-color:`
  127. // let info = params[0].axisValueLabel
  128. // for (let i = 0; i < params.length; i++) {
  129. // let param = params[i]
  130. // if (i === params.length - 1) {
  131. // info += `<br/>${circle}${param.color}"></span> ${param.seriesName}: ${totalData[param.dataIndex]}个`
  132. // } else {
  133. // if (param.value > 0) {
  134. // info += `<br/>${circle}${param.color}"></span> ${param.seriesName}: ${param.value}个`
  135. // }
  136. // }
  137. // }
  138. // return info
  139. // }
  140. // },
  141. // legend: {
  142. // type: 'scroll',
  143. // icon: 'circle',
  144. // data: types,
  145. // selectedMode: false,
  146. // textStyle: {
  147. // color: '#fff'
  148. // }
  149. // },
  150. // grid,
  151. // yAxis: {
  152. // type: 'value',
  153. // name: '个',
  154. // nameTextStyle: {
  155. // color: '#fff'
  156. // },
  157. // minInterval: 1,
  158. // interval: Math.ceil(maxValue / 5),
  159. // axisLabel: {
  160. // color: '#fff'
  161. // }
  162. // },
  163. // xAxis: {
  164. // type: 'category',
  165. // axisLabel: {
  166. // color: '#fff'
  167. // },
  168. // data: times
  169. // },
  170. // series
  171. // }
  172. // right3Ref.value.loadChart(option)
  173. // }
  174. function reloadRight3() {
  175. const option = {
  176. // backgroundColor: "#0B2D55",
  177. tooltip: {
  178. axisPointer: {
  179. type: 'cross'
  180. }
  181. },
  182. grid: {
  183. top: '14%',
  184. left: '2%',
  185. right: '4%',
  186. bottom: '5%',
  187. containLabel: true
  188. },
  189. xAxis: [{
  190. type: 'category',
  191. axisLine: { // 坐标轴轴线相关设置。数学上的x轴
  192. show: true,
  193. lineStyle: {
  194. color: '#233e64'
  195. }
  196. },
  197. axisLabel: { // 坐标轴刻度标签的相关设置
  198. color: '#02cacf'
  199. },
  200. axisTick: {show: false},
  201. data: ['1-16氯管', 'p3-16氯管', '3-16氯管']
  202. }],
  203. yAxis: [{
  204. name: '个',
  205. nameTextStyle: {
  206. color: '#02cacf'
  207. },
  208. min: value => (value.min - 1).toFixed(0),
  209. max: value => (value.max + 1).toFixed(0),
  210. axisLabel: {
  211. margin: 20,
  212. color: '#02cacf'
  213. },
  214. splitLine: {
  215. show: true,
  216. lineStyle: {
  217. color: '#233e64'
  218. }
  219. },
  220. axisLine: {
  221. show: true
  222. }
  223. }],
  224. series: [{
  225. name: '数量',
  226. type: 'bar',
  227. itemStyle: {
  228. color: function (params) {
  229. // 根据params的
  230. const colorsMap = [
  231. '#4768ec',
  232. '#92da76',
  233. '#dc8a5e'
  234. ]
  235. //返回对应的颜色
  236. return colorsMap[params.dataIndex]
  237. }
  238. },
  239. barWidth: 50,
  240. label: {
  241. show: true,
  242. position: 'top'
  243. },
  244. data: [3, 5, 6]
  245. }
  246. ]
  247. }
  248. right3Ref.value.loadChart(option)
  249. }
  250. onMounted(() => {
  251. // reloadRight3([])
  252. // reloadRight3()
  253. })
  254. onUnmounted(() => {
  255. // 关闭水质仪器视角
  256. if (deviceType.value === 'waterQuality') {
  257. View.closeDeviceView(route.params.stcd)
  258. }
  259. // 关闭 adcp 特效与弹窗
  260. if (device.value.ueDeviceName === "H-ADCP") {
  261. Label.setStationLabel(route.params.stcd, 'ADCP弹框', false)
  262. Label.adcpfx(route.params.stcd, false)
  263. }
  264. })
  265. </script>
  266. <template>
  267. <right-frame>
  268. <template #leftModule>
  269. <template v-if="['rainfall', 'flow','waterLevel'].includes(deviceType)">
  270. <card01 :title="device.deviceName" style="height: 65%">
  271. <h4 style="color: #00ccff">设备简介</h4>
  272. <el-row>
  273. <el-col :span="16">
  274. <p v-for="text in deviceDetail" class="introduce-text" v-html="text"></p>
  275. </el-col>
  276. <el-col :span="8">
  277. <img v-if="device.img" :src="device.img" alt="" class="introduce-float-img"/>
  278. </el-col>
  279. </el-row>
  280. <h4 style="color: #00ccff">维护记录</h4>
  281. <p>维护日期‌:2024年11月20日</p>
  282. <p>维护内容:</p>
  283. <p>·清洗采样过滤头及管路,检查位置确保采样顺利。</p>
  284. <p>·检查电源线路,确保干燥和稳定。</p>
  285. <p>·校准仪器,确保测量准确性。</p>
  286. </card01>
  287. <card01 style="height: 40%" title="设备维护情况">
  288. <stripe-table :columns="deviceStatusColumns" :data="deviceStatusData"></stripe-table>
  289. </card01>
  290. </template>
  291. <template v-if="deviceType === 'waterQuality'">
  292. <card01 :title="device.deviceName" style="height: 65%">
  293. <h4 style="color: #00ccff">设备简介</h4>
  294. <el-row>
  295. <el-col :span="16">
  296. <p v-for="text in deviceDetail" class="introduce-text" v-html="text"></p>
  297. </el-col>
  298. <el-col :span="8">
  299. <img v-if="device.img" :src="device.img" alt="" class="introduce-float-img"/>
  300. </el-col>
  301. </el-row>
  302. <h4 style="color: #00ccff">维护记录</h4>
  303. <p>维护日期‌:2024年11月20日</p>
  304. <p>维护内容:</p>
  305. <p>·清洗采样过滤头及管路,检查位置确保采样顺利。</p>
  306. <p>·检查电源线路,确保干燥和稳定。</p>
  307. <p>·校准仪器,确保测量准确性。</p>
  308. </card01>
  309. <card01 style="height: 40%" title="水质监测">
  310. <water-quality-analysis></water-quality-analysis>
  311. </card01>
  312. </template>
  313. </template>
  314. <template #rightModule>
  315. <template v-if="deviceType=== 'default'">
  316. <card01 :title="device.deviceName" style="height: 65%">
  317. <h4 style="color: #00ccff">设备简介</h4>
  318. <el-row>
  319. <el-col :span="16">
  320. <p v-for="text in deviceDetail" class="introduce-text" v-html="text"></p>
  321. </el-col>
  322. <el-col :span="8">
  323. <img v-if="device.img" :src="device.img" alt="" class="introduce-float-img"/>
  324. </el-col>
  325. </el-row>
  326. <h4 style="color: #00ccff">维护记录</h4>
  327. <p>维护日期‌:2024年11月20日</p>
  328. <p>维护内容:</p>
  329. <p>·清洗采样过滤头及管路,检查位置确保采样顺利。</p>
  330. <p>·检查电源线路,确保干燥和稳定。</p>
  331. <p>·校准仪器,确保测量准确性。</p>
  332. </card01>
  333. <card01 style="height: 40%" title="设备维护情况">
  334. <stripe-table :columns="deviceStatusColumns" :data="deviceStatusData"></stripe-table>
  335. </card01>
  336. </template>
  337. <template v-if="deviceType=== 'video'">
  338. <card01 style="height: 40%" title="视频监控">
  339. <gw-video :code="videoCode" :imageSrc="videoImageSrc"></gw-video>
  340. </card01>
  341. </template>
  342. <template v-if="deviceType=== 'waterLevel'">
  343. <card01 style="height: 36%" title="水位监测">
  344. <water-level></water-level>
  345. </card01>
  346. </template>
  347. <template v-if="deviceType=== 'rainfall'">
  348. <card01 style="height: 36%" title="雨量监测">
  349. <rainfall></rainfall>
  350. </card01>
  351. </template>
  352. <template v-if="deviceType=== 'flow'">
  353. <card01 style="height: 36%" title="流量监测">
  354. <adcp-flow></adcp-flow>
  355. <!-- <adcp-flow v-if="device.ueDeviceName === '无人船'"></adcp-flow>-->
  356. <!-- <flow v-else></flow>-->
  357. </card01>
  358. </template>
  359. <template v-if="deviceType=== 'waterQuality'">
  360. <card01 style="height: 33%" title="设备维护情况">
  361. <stripe-table :columns="deviceStatusColumns" :data="deviceStatusData"></stripe-table>
  362. </card01>
  363. <card01 style="height: 33%" title="配件运维信息">
  364. <stripe-table :columns="accessoriesColumns" :data="accessoriesData"></stripe-table>
  365. </card01>
  366. <card01 style="height: 33%" title="耗材余量监控">
  367. <chart ref="right3Ref"></chart>
  368. </card01>
  369. </template>
  370. </template>
  371. <template #btnGroup>
  372. <station-right-button-group></station-right-button-group>
  373. </template>
  374. </right-frame>
  375. </template>
  376. <style lang="scss" scoped>
  377. @use "@/assets/styles/introduce.scss";
  378. </style>