dust-detail.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. <template>
  2. <view class="dust-detail">
  3. <u-tabs
  4. class="devic-box-tab"
  5. :current="PageCur"
  6. :list="tabList"
  7. @click="NavChange"
  8. ></u-tabs>
  9. <view class="dust-content">
  10. <view class="top-area" v-for="(item, index) in topList" :key="index">
  11. <view class="top-title">
  12. <view style="font-weight: bold">{{ item.label }}</view>
  13. </view>
  14. <view class="top-card">
  15. <view class="card-item card-item1">
  16. <view class="item-box item-box1">
  17. <view class="box-val">{{ item.temperature || "--" }}</view>
  18. <view class="box-name">温度(℃)</view>
  19. </view>
  20. </view>
  21. <view class="card-item card-item1">
  22. <view class="item-box item-box2">
  23. <view class="box-val">{{ item.dustval || "--" }}</view>
  24. <view class="box-name">粉尘浓度(mg/m³)</view>
  25. </view>
  26. </view>
  27. <view class="card-item">
  28. <view class="item-box item-box3">
  29. <view class="box-val">{{ item.waterPressure || "--" }}</view>
  30. <view class="box-name">喷雾水压(MPa)</view>
  31. </view>
  32. </view>
  33. <view class="card-item">
  34. <view class="item-box item-box4">
  35. <view class="box-val">{{ item.atomizingState || "--" }}</view>
  36. <view class="box-name">喷雾状态</view>
  37. </view>
  38. </view>
  39. </view>
  40. <view class="top-echart">
  41. <LineChart
  42. :chartData="option"
  43. :style="{ width: '100%', height: '180px' }"
  44. ></LineChart>
  45. </view>
  46. </view>
  47. <view class="bot-area">
  48. <view class="bot-title">
  49. <view style="font-weight: bold">粉尘监控测点信息</view>
  50. </view>
  51. <view class="bot-content">
  52. <view
  53. class="card-b"
  54. v-for="(item, index) in cardListDust"
  55. :key="index"
  56. >
  57. <div class="item-l">
  58. <div class="label-l">{{ item.label || "--" }}</div>
  59. <div class="value-l">{{ item.value || "--" }}</div>
  60. </div>
  61. <div class="item-r">
  62. <div
  63. class="content-r"
  64. v-for="(items, ind) in item.listR"
  65. :key="ind"
  66. >
  67. <span>{{ `${items.label} : ` }}</span>
  68. <span
  69. :class="{
  70. 'status-f': items.value == 1,
  71. 'status-l': items.value == 0,
  72. }"
  73. >{{ `${items.value}${items.dw}` || "--" }}</span
  74. >
  75. </div>
  76. </div>
  77. </view>
  78. </view>
  79. </view>
  80. </view>
  81. </view>
  82. </template>
  83. <script>
  84. import api from "@/api/api";
  85. export default {
  86. name: "dustDetail",
  87. props: {},
  88. watch: {},
  89. data() {
  90. return {
  91. option: {},
  92. timer: "",
  93. PageCur: "0",
  94. tabList: [],
  95. //喷粉选项数据
  96. topList: [],
  97. flag: true,
  98. echartNow: [],
  99. echartYc: [],
  100. xData: [],
  101. yDataN: [],
  102. yDataY: [],
  103. yDataS: [],
  104. maxY: 0,
  105. cardListDust: [],
  106. };
  107. },
  108. beforeDestroy() {
  109. this.myChart.clear();
  110. this.myChart.dispose();
  111. this.timer = null;
  112. clearTimeout(this.timer);
  113. },
  114. mounted() {
  115. this.getTabList();
  116. this.getWindDeviceList();
  117. },
  118. methods: {
  119. NavChange: function (item) {
  120. clearTimeout(this.timer);
  121. this.PageCur = item.index;
  122. this.getMonitor(this.tabList[this.PageCur].deviceID, true);
  123. },
  124. getMonitor(deviceID, flag) {
  125. let than = this;
  126. than.timer = setTimeout(
  127. async () => {
  128. await than.getSysWarnList(deviceID, "dust");
  129. if (than.timer) {
  130. than.timer = null;
  131. }
  132. than.getMonitor(deviceID);
  133. },
  134. flag ? 0 : 3000
  135. );
  136. },
  137. //获取顶部tab选项数据
  138. getTabList() {
  139. this.tabList = [];
  140. new Promise((resolve, reject) => {
  141. api
  142. .sysTypeWarn({ type: "dust" })
  143. .then((response) => {
  144. if (response.data.code == 200 && response.data.result.length != 0) {
  145. let result = response.data.result;
  146. console.log(result, "粉尘菜单---------");
  147. result.forEach((el) => {
  148. this.tabList.push({
  149. name: el.systemname,
  150. warn: "低风险",
  151. deviceID: el.id,
  152. strtype: el.strtype,
  153. });
  154. });
  155. this.getMonitor(this.tabList[0].deviceID, true);
  156. } else {
  157. reject(response);
  158. }
  159. })
  160. .catch((error) => {
  161. console.log("catch===>response", response);
  162. reject(error);
  163. });
  164. });
  165. },
  166. //获取喷粉选项数据
  167. getSysWarnList(id, type) {
  168. let that = this;
  169. new Promise((resolve, reject) => {
  170. api
  171. .sysWarn({ sysid: id, type: type })
  172. .then((response) => {
  173. if (response.data.code == 200) {
  174. console.log(response.data, "喷粉选项数据---------");
  175. let data = response.data.result.dust;
  176. if (data.length != 0) {
  177. that.topList = data.map((el) => {
  178. return {
  179. label: el.strinstallpos,
  180. temperature: el.readData.temperature,
  181. dustval: el.readData.dustval,
  182. waterPressure: el.readData.waterPressure,
  183. atomizingState: el.readData.atomizingState,
  184. };
  185. });
  186. data.forEach((v, index) => {
  187. if (that.flag) {
  188. that.echartNow = JSON.parse(v.readData.expectInfo)["list"];
  189. that.flag = false;
  190. }
  191. that.echartYc.push({
  192. time: JSON.parse(v.readData.expectInfo)["nowTime"],
  193. value: JSON.parse(v.readData.expectInfo)["nowVal"],
  194. });
  195. let setData = [...that.echartNow, ...that.echartYc].sort(
  196. (a, b) =>
  197. Date.parse(new Date(a.time)) -
  198. Date.parse(new Date(b.time))
  199. );
  200. that.xData = [];
  201. that.yDataS = [];
  202. that.yDataY = [];
  203. that.yDataN = [];
  204. setData.forEach((el) => {
  205. if (el.value && el.value != "0") {
  206. that.xData.push(el.time);
  207. that.yDataS.push(el.value);
  208. that.yDataY.push(
  209. JSON.parse(v.readData.expectInfo)["aveVal"]
  210. );
  211. that.yDataN.push(
  212. JSON.parse(v.readData.expectInfo)["fmin"]
  213. ? JSON.parse(v.readData.expectInfo)["fmin"]
  214. : 0
  215. );
  216. }
  217. });
  218. let max = that.yDataS.reduce((acr, cur) => {
  219. return acr > cur ? acr : cur;
  220. });
  221. that.maxY = that.formatRoundNum(max * 1.5);
  222. // console.log(that.xData, that.yDataS, that.yDataY, that.yDataN, '000')
  223. this.option = {
  224. categories: this.xData.slice(-3) || [],
  225. series: [
  226. {
  227. name: "预测值",
  228. data: this.yDataY.slice(-3) || [],
  229. },
  230. {
  231. name: "最新值",
  232. data: this.yDataN.slice(-3) || [],
  233. },
  234. ],
  235. };
  236. });
  237. }
  238. } else {
  239. reject(response);
  240. }
  241. })
  242. .catch((error) => {
  243. console.log("catch===>response", response);
  244. reject(error);
  245. });
  246. });
  247. },
  248. //获取粉尘监控测点信息
  249. getWindDeviceList() {
  250. new Promise((resolve, reject) => {
  251. api
  252. .getDeviceVent({ devicetype: "dusting", pagetype: "normal" })
  253. .then((response) => {
  254. if (response.data.code == 200) {
  255. let data = response.data.result;
  256. if (data.msgTxt[0].datalist.length != 0) {
  257. let list = data.msgTxt[0].datalist;
  258. if (list.length > 0) {
  259. this.cardListDust = list.map((el) => {
  260. //lxh
  261. const readData = el.readData;
  262. el = Object.assign(el, readData);
  263. return {
  264. label: "通信状态",
  265. value: el.netStatus == "0" ? "断开" : "连接",
  266. listR: [
  267. {
  268. id: 0,
  269. label: "安装位置",
  270. dw: "",
  271. value: el.strinstallpos,
  272. },
  273. {
  274. id: 1,
  275. label: "粉尘浓度",
  276. dw: "(mg/m³)",
  277. value: el.dustval,
  278. },
  279. {
  280. id: 2,
  281. label: "巷道湿度",
  282. dw: "(RH)",
  283. value: el.humidity,
  284. },
  285. {
  286. id: 4,
  287. label: "巷道温度",
  288. dw: "(℃)",
  289. value: el.temperature,
  290. },
  291. {
  292. id: 3,
  293. label: "是否报警",
  294. dw: "",
  295. value:
  296. el.warnFlag == "0"
  297. ? "正常"
  298. : el.warnFlag == 1
  299. ? "报警"
  300. : el.warnFlag == 2
  301. ? "断开"
  302. : "未监测",
  303. },
  304. ],
  305. };
  306. });
  307. }
  308. }
  309. } else {
  310. reject(response);
  311. }
  312. })
  313. .catch((error) => {
  314. console.log("catch===>response", response);
  315. reject(error);
  316. });
  317. });
  318. },
  319. formatRoundNum(num) {
  320. let interger = Math.ceil(num);
  321. let leng = String(interger).length;
  322. return (
  323. Math.ceil(interger / Math.pow(10, leng - 1)) * Math.pow(10, leng - 1)
  324. );
  325. },
  326. },
  327. computed: {},
  328. };
  329. </script>
  330. <style lang="scss" scoped>
  331. .dust-detail {
  332. position: relative;
  333. // padding: 0px 10px;
  334. box-sizing: border-box;
  335. .devic-box-tab {
  336. padding: 0px 10px !important;
  337. }
  338. .dust-content {
  339. // height: 704px;
  340. // padding: 0px 10px;
  341. // box-sizing: border-box;
  342. // overflow-y: auto;
  343. height: 704px;
  344. box-sizing: border-box;
  345. overflow-y: auto;
  346. .top-area {
  347. width: 100%;
  348. padding: 10px;
  349. box-sizing: border-box;
  350. background-color: #fff;
  351. margin-bottom: 2px;
  352. .top-title {
  353. height: 28px;
  354. margin-bottom: 10px;
  355. display: flex;
  356. justify-content: space-between;
  357. align-items: center;
  358. }
  359. .top-card {
  360. display: flex;
  361. justify-content: space-between;
  362. align-items: flex-start;
  363. flex-wrap: wrap;
  364. width: 100%;
  365. margin-bottom: 10px;
  366. .card-item {
  367. width: calc(50% - 5px);
  368. height: 60px;
  369. border-radius: 5px;
  370. background: linear-gradient(
  371. to right,
  372. rgba(55, 135, 254, 0.08),
  373. rgba(4, 184, 255, 0.08),
  374. rgba(60, 161, 237, 0.08)
  375. );
  376. .item-box {
  377. display: flex;
  378. flex-direction: column;
  379. justify-content: center;
  380. align-items: flex-start;
  381. width: 100%;
  382. height: 100%;
  383. padding: 0px 15px;
  384. .box-val {
  385. height: 28px;
  386. line-height: 28px;
  387. color: #0eb4fc;
  388. font-weight: bold;
  389. }
  390. .box-name {
  391. font-size: 12px;
  392. }
  393. }
  394. .item-box1 {
  395. background: url("/static/wd.png") no-repeat right;
  396. background-size: 30% 80%;
  397. }
  398. .item-box2 {
  399. background: url("/static/dust.png") no-repeat right;
  400. background-size: 30% 80%;
  401. }
  402. .item-box3 {
  403. background: url("/static/pwsy.png") no-repeat right;
  404. background-size: 30% 80%;
  405. }
  406. .item-box4 {
  407. background: url("/static/pwzt.png") no-repeat right;
  408. background-size: 30% 80%;
  409. }
  410. }
  411. .card-item1 {
  412. margin-bottom: 10px;
  413. }
  414. }
  415. .top-echart {
  416. height: 220px;
  417. }
  418. }
  419. .bot-area {
  420. width: 100%;
  421. padding: 10px;
  422. box-sizing: border-box;
  423. background-color: #fff;
  424. margin-bottom: 2px;
  425. .bot-title {
  426. height: 28px;
  427. margin-bottom: 10px;
  428. display: flex;
  429. justify-content: space-between;
  430. align-items: center;
  431. }
  432. .bot-content {
  433. // height: calc(100% - 38px);
  434. overflow-y: auto;
  435. .card-b {
  436. width: 100%;
  437. height: 100px;
  438. display: flex;
  439. justify-content: space-between;
  440. padding: 5px;
  441. margin-bottom: 5px;
  442. background: linear-gradient(
  443. to right,
  444. rgba(55, 135, 254, 0.08),
  445. rgba(4, 184, 255, 0.08),
  446. rgba(60, 161, 237, 0.08)
  447. );
  448. .item-l {
  449. position: relative;
  450. width: 80px;
  451. height: 100%;
  452. background: url("/static/bot-area.png") no-repeat center;
  453. background-size: 100% 100%;
  454. .label-l {
  455. width: 100%;
  456. position: absolute;
  457. top: 7px;
  458. font-size: 12px;
  459. text-align: center;
  460. }
  461. .value-l {
  462. width: 100%;
  463. position: absolute;
  464. top: 50px;
  465. color: #0eb4fc;
  466. text-align: center;
  467. }
  468. }
  469. .item-r {
  470. width: calc(100% - 100px);
  471. height: 100%;
  472. display: flex;
  473. flex-direction: column;
  474. justify-content: space-around;
  475. .content-r {
  476. display: flex;
  477. span {
  478. font-size: 12px;
  479. &:first-child {
  480. display: inline-block;
  481. width: 68px;
  482. }
  483. &:last-child {
  484. display: inline-block;
  485. width: calc(100% - 68px);
  486. overflow: hidden;
  487. white-space: nowrap;
  488. /* 不换行 */
  489. /* 超出部分隐藏 */
  490. text-overflow: ellipsis;
  491. /* 使用省略符号 */
  492. }
  493. }
  494. .status-f {
  495. color: #ff0000;
  496. }
  497. .status-l {
  498. color: #3df6ff;
  499. }
  500. }
  501. }
  502. }
  503. }
  504. }
  505. }
  506. }
  507. </style>