SandTable.vue 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414
  1. <template>
  2. <div class="sand-table" id="sandTable">
  3. <img :src="require('@assets/png/3dback.png')" class="i3dback" />
  4. <!-- <img :src="require('@assets/png/3dcloud.png')" class="i3dcloud" /> -->
  5. <StBack></StBack>
  6. <ThreeModel1
  7. class="three-model-layer"
  8. :data="mapSource"
  9. @when="when"
  10. @clickMapItem="clickMapItem"
  11. ></ThreeModel1>
  12. <div class="sand-table-left" v-if="showPanel">
  13. <PanelSand
  14. class="left-panel"
  15. title="气象预测"
  16. :subTitle="timeStr + '实况'"
  17. >
  18. <weather
  19. class="pd-t-16"
  20. style="cursor: pointer"
  21. :data="tqmap1"
  22. @click="openWeatherDialog"
  23. />
  24. </PanelSand>
  25. <PanelSand class="left-panel mg-t-16" title="健康推荐">
  26. <RankTable :data="rmls" @rowClick="clickHealthRow"></RankTable>
  27. </PanelSand>
  28. <PanelSand class="left-panel mg-t-16" title="停机信息">
  29. <RankTable :data="sels" @rowClick="clickStopRow"></RankTable>
  30. <!-- <ComTable :data="sels"></ComTable> -->
  31. </PanelSand>
  32. <PanelSandToolbar class="left-panel mg-t-16" title="隐患情况">
  33. <template v-slot:tools>
  34. <div class="exchange" @click="changeWarnSwitch">
  35. <span :class="warnSwitch ? 'gray' : 'green'">预警</span>
  36. <i class="green fa fa-exchange mg-l-8 mg-r-8"></i>
  37. <span :class="warnSwitch ? 'green' : 'gray'">故障</span>
  38. </div>
  39. </template>
  40. <template v-slot:default>
  41. <RadarPieChart
  42. height="20.6vh"
  43. :list="warnChartData"
  44. title="隐患情况"
  45. />
  46. </template>
  47. </PanelSandToolbar>
  48. </div>
  49. <div class="sand-table-right" v-if="showPanel">
  50. <PanelSand class="right-panel" title="视频监控">
  51. <!-- <el-row v-for="(pItem, pIndex) in videoArray" :key="pIndex">
  52. <el-col
  53. :span="12"
  54. class="pre-img-box"
  55. v-for="(cItem, cIndex) in pItem"
  56. :key="cIndex"
  57. @click="openVideoDialog(cItem)"
  58. >
  59. <div class="mask"></div>
  60. <iframe
  61. class="pre-img videoBoxiframe"
  62. :class="cItem.class"
  63. width="95%"
  64. height="8.657vh"
  65. :src="cItem.url + cItem.token"
  66. v-if="cItem.switch"
  67. />
  68. </el-col> -->
  69. <el-row v-for="(pItem, pIndex) in videoArray1" :key="pIndex">
  70. <el-col
  71. :span="12"
  72. class="pre-img-box"
  73. v-for="(cItem, cIndex) in pItem"
  74. :key="cIndex"
  75. @click="openVideoDialog1(cItem)"
  76. >
  77. <div class="mask"></div>
  78. <hlsVideo
  79. class="pre-img videoBoxiframe"
  80. width="95%"
  81. height="8.657vh"
  82. :code="cItem.code"
  83. :class="cItem.class"
  84. v-if="cItem.switch"
  85. />
  86. <!-- <iframe
  87. class="pre-img videoBoxiframe"
  88. :class="cItem.class"
  89. width="95%"
  90. height="8.657vh"
  91. src="http://192.168.1.18:1935/hls/NSS_FDC_ZK/index.m3u8"
  92. v-if="cItem.switch"
  93. /> -->
  94. </el-col>
  95. </el-row>
  96. </PanelSand>
  97. <PanelSand class="right-panel mg-t-16" title="工单管理">
  98. <div
  99. class="person-info-box mg-t-16 animated a0"
  100. :class="peopleClass"
  101. v-if="workData.data[0]"
  102. >
  103. <img
  104. class="header mg-r-8 bg-green"
  105. style="width: 75px; height: 75px; cursor: pointer"
  106. :src="workData.data[workDataIndex].imgurl"
  107. @click="jumpUrl('/health/frist?tab=2')"
  108. />
  109. <div class="person-info">
  110. <div class="green font-lg" style="font-weight: bold">
  111. {{ workData.data[workDataIndex].laborname }}
  112. </div>
  113. <div class="white font-sm">
  114. <span>职务:{{ workData.data[workDataIndex].jobcode }}</span>
  115. <!-- <span class="mg-l-16">当前任务编号 000000</span> -->
  116. </div>
  117. <div class="white font-sm">
  118. <!-- 平均检修时间 <span class="green">5</span> 小时 -->
  119. 开始时间
  120. <span class="green">{{
  121. workData.data[workDataIndex].starttime
  122. }}</span>
  123. </div>
  124. </div>
  125. </div>
  126. <div class="table mg-t-8" style="min-height: 180px">
  127. <Table :data="workData" />
  128. </div>
  129. </PanelSand>
  130. <PanelSandToolbar class="right-panel mg-t-16" title="部件">
  131. <template v-slot:tools>
  132. <div class="exchange" @click="changeBjSwitch">
  133. <span :class="bjSwitch ? 'gray' : 'green'">库存</span>
  134. <i class="green fa fa-exchange mg-l-8 mg-r-8"></i>
  135. <span :class="bjSwitch ? 'green' : 'gray'">记录</span>
  136. </div>
  137. </template>
  138. <template v-slot:default>
  139. <RadarPieChart height="21vh" :list="bjChartData" title="部件情况" />
  140. </template>
  141. </PanelSandToolbar>
  142. </div>
  143. <div class="sand-table-bottom" :style="$store.state.themeName === 'dark' ? 'right: calc(50vw - 545px);' : 'right: calc(50vw - 590px);'" v-if="showPanel">
  144. <Ppanel
  145. title="利用小时"
  146. :data="riseNumber(gxkmap.bg_dxkyss)"
  147. dataColor="#05BB4C"
  148. :days="gxkmap.ydxkyss"
  149. :data1Icon="
  150. gxkmap.tb_dxkyss < 0 ? 'svg-arrow-dpwn-1' : 'svg-arrow-up-1'
  151. "
  152. :data1IconClass="
  153. gxkmap.tb_dxkyss < 0
  154. ? 'svg-icon-sm svg-icon-yellow'
  155. : 'svg-icon-sm svg-icon-green'
  156. "
  157. :data2Icon="
  158. gxkmap.hb_dxkyss < 0 ? 'svg-arrow-dpwn-1' : 'svg-arrow-up-1'
  159. "
  160. :data2IconClass="
  161. gxkmap.hb_dxkyss < 0
  162. ? 'svg-icon-sm svg-icon-yellow'
  163. : 'svg-icon-sm svg-icon-green'
  164. "
  165. ></Ppanel>
  166. <Ppanel
  167. title="设备可利用率"
  168. class="stb-p"
  169. :data="riseNumber(gxkmap.bg_sbklyl)"
  170. dataColor="#05BB4C"
  171. daysUnit="%"
  172. :days="gxkmap.ysbklyl"
  173. :data1Icon="
  174. gxkmap.hb_sbklyl < 0 ? 'svg-arrow-dpwn-1' : 'svg-arrow-up-1'
  175. "
  176. :data1IconClass="
  177. gxkmap.hb_sbklyl < 0
  178. ? 'svg-icon-sm svg-icon-yellow'
  179. : 'svg-icon-sm svg-icon-green'
  180. "
  181. :data2Icon="
  182. gxkmap.tb_sbklyl < 0 ? 'svg-arrow-dpwn-1' : 'svg-arrow-up-1'
  183. "
  184. :data2IconClass="
  185. gxkmap.tb_sbklyl < 0
  186. ? 'svg-icon-sm svg-icon-yellow'
  187. : 'svg-icon-sm svg-icon-green'
  188. "
  189. ></Ppanel>
  190. <Ppanel
  191. title="MTBF"
  192. class="stb-p"
  193. :data="'0.1' || riseNumber(gxkmap.bg_mtbf)"
  194. dataColor="#05BB4C"
  195. :days="gxkmap.mtbf"
  196. :data1Icon="gxkmap.hb_mtbf < 0 ? 'svg-arrow-dpwn-1' : 'svg-arrow-up-1'"
  197. :data1IconClass="
  198. gxkmap.hb_mtbf < 0
  199. ? 'svg-icon-sm svg-icon-yellow'
  200. : 'svg-icon-sm svg-icon-green'
  201. "
  202. :data2Icon="gxkmap.tb_mtbf < 0 ? 'svg-arrow-dpwn-1' : 'svg-arrow-up-1'"
  203. :data2IconClass="
  204. gxkmap.tb_mtbf < 0
  205. ? 'svg-icon-sm svg-icon-yellow'
  206. : 'svg-icon-sm svg-icon-green'
  207. "
  208. ></Ppanel>
  209. <Ppanel
  210. title="MTTR"
  211. class="stb-p"
  212. :data="'0.1' || riseNumber(gxkmap.bg_mttr)"
  213. dataColor="#05BB4C"
  214. :days="gxkmap.mttr"
  215. :data1Icon="gxkmap.hb_mttr < 0 ? 'svg-arrow-dpwn-1' : 'svg-arrow-up-1'"
  216. :data1IconClass="
  217. gxkmap.hb_mttr < 0
  218. ? 'svg-icon-sm svg-icon-yellow'
  219. : 'svg-icon-sm svg-icon-green'
  220. "
  221. :data2Icon="gxkmap.tb_mttr < 0 ? 'svg-arrow-dpwn-1' : 'svg-arrow-up-1'"
  222. :data2IconClass="
  223. gxkmap.tb_mttr < 0
  224. ? 'svg-icon-sm svg-icon-yellow'
  225. : 'svg-icon-sm svg-icon-green'
  226. "
  227. ></Ppanel>
  228. <Ppanel
  229. title="MTTF"
  230. class="stb-p"
  231. :data="'0.1' || riseNumber(gxkmap.bg_mttf)"
  232. dataColor="#05BB4C"
  233. :days="gxkmap.mttf"
  234. :data1Icon="gxkmap.hb_mttf < 0 ? 'svg-arrow-dpwn-1' : 'svg-arrow-up-1'"
  235. :data1IconClass="
  236. gxkmap.hb_mttf < 0
  237. ? 'svg-icon-sm svg-icon-yellow'
  238. : 'svg-icon-sm svg-icon-green'
  239. "
  240. :data2Icon="gxkmap.tb_mttf < 0 ? 'svg-arrow-dpwn-1' : 'svg-arrow-up-1'"
  241. :data2IconClass="
  242. gxkmap.tb_mttf < 0
  243. ? 'svg-icon-sm svg-icon-yellow'
  244. : 'svg-icon-sm svg-icon-green'
  245. "
  246. ></Ppanel>
  247. </div>
  248. <el-dialog
  249. title=""
  250. :custom-class="tableDialogClass"
  251. v-model="showHealthDialog"
  252. width="80%"
  253. :destroy-on-close="true"
  254. :before-close="
  255. (done) => {
  256. tableDialogClass = 'modal animated a1 fadeOutLeftBig';
  257. delaylyFn(450, done);
  258. }
  259. "
  260. @closed="
  261. dialogVideoUrl = '';
  262. tableDialogClass = 'modal animated a1 fadeInLeftBig';
  263. "
  264. >
  265. <template #title>
  266. <div class="dialogTitle">
  267. 健康推荐详情
  268. <i class="jumpBtn el-icon-more" @click="jumpUrl('/health/frist')"></i>
  269. </div>
  270. </template>
  271. <el-form style="margin: 30px 0" label-width="120px" inline>
  272. <el-form-item label="风机ID" style="width: 45%; margin-bottom: 25px">
  273. <el-input v-model="tableItem.wtId" readonly></el-input>
  274. </el-form-item>
  275. <el-form-item label="检修类型" style="width: 45%; margin-bottom: 25px">
  276. <el-input v-model="tableItem.operation" readonly></el-input>
  277. </el-form-item>
  278. <el-form-item label="推荐理由" style="width: 45%; margin-bottom: 25px">
  279. <el-input v-model="tableItem.reason" readonly></el-input>
  280. </el-form-item>
  281. <el-form-item label="推荐日期" style="width: 45%; margin-bottom: 25px">
  282. <el-input v-model="tableItem.recodedate" readonly></el-input>
  283. </el-form-item>
  284. <el-form-item label="风速" style="width: 45%; margin-bottom: 25px">
  285. <el-input v-model="tableItem.speed" readonly></el-input>
  286. </el-form-item>
  287. <el-form-item label="预警名称" style="width: 45%; margin-bottom: 25px">
  288. <el-input v-model="tableItem.typename" readonly></el-input>
  289. </el-form-item>
  290. </el-form>
  291. </el-dialog>
  292. <el-dialog
  293. title=""
  294. :custom-class="tableDialogClass"
  295. v-model="showTableDialog"
  296. width="80%"
  297. :destroy-on-close="true"
  298. :before-close="
  299. (done) => {
  300. tableDialogClass = 'modal animated a1 fadeOutLeftBig';
  301. delaylyFn(450, done);
  302. }
  303. "
  304. @closed="
  305. dialogVideoUrl = '';
  306. tableDialogClass = 'modal animated a1 fadeInLeftBig';
  307. "
  308. >
  309. <template #title>
  310. <div class="dialogTitle">
  311. 停机详情
  312. <i
  313. class="jumpBtn el-icon-more"
  314. @click="jumpUrl('/health/gzzd/malfunctionRecall')"
  315. ></i>
  316. </div>
  317. </template>
  318. <el-form style="margin: 30px 0" label-width="120px" inline>
  319. <el-form-item label="风机ID" style="width: 45%; margin-bottom: 25px">
  320. <el-input v-model="tableItem.windTurbineId" readonly></el-input>
  321. </el-form-item>
  322. <el-form-item label="所属风场" style="width: 45%; margin-bottom: 25px">
  323. <el-input v-model="tableItem.wpName" readonly></el-input>
  324. </el-form-item>
  325. <el-form-item label="停机类型" style="width: 45%; margin-bottom: 25px">
  326. <el-input v-model="tableItem.statusName" readonly></el-input>
  327. </el-form-item>
  328. <el-form-item label="停机时间" style="width: 45%; margin-bottom: 25px">
  329. <el-input v-model="tableItem.stopTime" readonly></el-input>
  330. </el-form-item>
  331. <el-form-item label="恢复时间" style="width: 45%; margin-bottom: 25px">
  332. <el-input v-model="tableItem.startTime" readonly></el-input>
  333. </el-form-item>
  334. <el-form-item
  335. label="停机时长(小时)"
  336. style="width: 45%; margin-bottom: 25px"
  337. >
  338. <el-input v-model="tableItem.stopHours" readonly></el-input>
  339. </el-form-item>
  340. </el-form>
  341. </el-dialog>
  342. <el-dialog
  343. title="天气详情"
  344. :custom-class="tableDialogClass"
  345. v-model="showWeatherDialog"
  346. width="80%"
  347. :destroy-on-close="true"
  348. :before-close="
  349. (done) => {
  350. tableDialogClass = 'modal animated a1 fadeOutLeftBig';
  351. delaylyFn(450, done);
  352. }
  353. "
  354. @closed="tableDialogClass = 'modal animated a1 fadeInLeftBig'"
  355. >
  356. <div class="weatherBox">
  357. <div class="l">
  358. <DoubleLineChart :height="'100%'" :list="weatherChart" />
  359. </div>
  360. <div class="r">
  361. <el-collapse
  362. style="height: 400px; overflow-y: scroll"
  363. v-model="weathercollapse"
  364. accordion
  365. >
  366. <el-collapse-item
  367. :name="index"
  368. v-for="(item, index) in tqmap5"
  369. :key="index"
  370. >
  371. <template #title>
  372. <div class="collapseItemTitle">
  373. {{ item.time }}
  374. <div
  375. style="
  376. display: flex;
  377. justify-content: start;
  378. align-items: center;
  379. "
  380. >
  381. <div class="icon svg-icon svg-icon-white">
  382. <SvgIcon class="svg" :svgid="'svg-' + item.tqtp" />
  383. </div>
  384. <div class="info">{{ item.sd }}% / {{ item.wd }}°C</div>
  385. </div>
  386. <div class="otherWea">{{ item.tqmc }}</div>
  387. </div>
  388. </template>
  389. <div class="other-info">
  390. <Row>
  391. <Col>
  392. <div class="svg-icon svg-icon-sm svg-icon-green other-icon">
  393. <svg-icon svgid="svg-能见度" />
  394. </div>
  395. <div class="value">{{ item.qxd }}</div>
  396. <div class="text">能见度</div>
  397. </Col>
  398. <Col>
  399. <div class="svg-icon svg-icon-sm svg-icon-green other-icon">
  400. <svg-icon svgid="svg-湿度" />
  401. </div>
  402. <div class="value">{{ item.sd }}</div>
  403. <div class="text">湿度</div>
  404. </Col>
  405. <Col>
  406. <div class="svg-icon svg-icon-sm svg-icon-green other-icon">
  407. <svg-icon svgid="svg-气压" />
  408. </div>
  409. <div class="value">{{ item.dqyl }}</div>
  410. <div class="text">气压</div>
  411. </Col>
  412. <Col>
  413. <div class="svg-icon svg-icon-sm svg-icon-green other-icon">
  414. <svg-icon svgid="svg-日出" />
  415. </div>
  416. <div class="value">{{ item.richushijian }}</div>
  417. <div class="text">日出时间</div>
  418. </Col>
  419. <Col>
  420. <div class="svg-icon svg-icon-sm svg-icon-green other-icon">
  421. <svg-icon svgid="svg-日落" />
  422. </div>
  423. <div class="value">{{ item.riluoshijian }}</div>
  424. <div class="text">日落时间</div>
  425. </Col>
  426. </Row>
  427. </div>
  428. </el-collapse-item>
  429. </el-collapse>
  430. </div>
  431. </div>
  432. </el-dialog>
  433. <el-dialog
  434. top="50px"
  435. title="查看视频"
  436. :custom-class="videoDialogClass"
  437. v-model="showVideoDialog"
  438. width="80%"
  439. :destroy-on-close="true"
  440. :before-close="
  441. (done) => {
  442. videoDialogClass = 'modal animated a1 bounceOut';
  443. delaylyFn(450, done);
  444. }
  445. "
  446. @closed="
  447. dialogVideoUrl = '';
  448. videoDialogClass = 'modal animated a1 bounceIn';
  449. "
  450. >
  451. <!-- <iframe
  452. class="videoBoxiframe"
  453. width="95%"
  454. height="800px"
  455. :src="dialogVideoUrl"
  456. /> -->
  457. <hlsVideo
  458. class="videoBoxiframe"
  459. width="95%"
  460. height="800px"
  461. :code="dialogVideoUrl"
  462. />
  463. </el-dialog>
  464. <el-dialog
  465. title="场站综合评分"
  466. :custom-class="mainInfoDialogClass"
  467. v-model="showMainInfoDialog"
  468. width="80%"
  469. :destroy-on-close="true"
  470. :before-close="
  471. (done) => {
  472. mainInfoDialogClass = 'modal curModal animated a1 fadeOutUpBig';
  473. delaylyFn(450, done);
  474. }
  475. "
  476. @closed="mainInfoDialogClass = 'modal curModal animated a0 fadeInDown'"
  477. >
  478. <div v-for="(item, index) in mainInfo" :key="index">
  479. <el-divider content-position="center">{{ item.name }}</el-divider>
  480. <el-form style="margin: 30px 0" label-width="120px" inline>
  481. <el-form-item
  482. label="风能利用率"
  483. style="width: 45%; margin-bottom: 25px"
  484. >
  485. <el-input v-model="item.actualpower" readonly></el-input>
  486. </el-form-item>
  487. <el-form-item
  488. label="综合厂用电率(%)"
  489. style="width: 45%; margin-bottom: 25px"
  490. >
  491. <el-input v-model="item.comprehensiverate" readonly></el-input>
  492. </el-form-item>
  493. <el-form-item
  494. label="利用小时(小时)"
  495. style="width: 45%; margin-bottom: 25px"
  496. >
  497. <el-input v-model="item.utilizationhours" readonly></el-input>
  498. </el-form-item>
  499. <el-form-item
  500. label="设备可利用率(%)"
  501. style="width: 45%; margin-bottom: 25px"
  502. >
  503. <el-input v-model="item.availability" readonly></el-input>
  504. </el-form-item>
  505. <el-form-item
  506. label="MTBF(小时)"
  507. style="width: 45%; margin-bottom: 25px"
  508. >
  509. <el-input v-model="item.mtbf" readonly></el-input>
  510. </el-form-item>
  511. <el-form-item
  512. label="MTTR(小时)"
  513. style="width: 45%; margin-bottom: 25px"
  514. >
  515. <el-input v-model="item.mttr" readonly></el-input>
  516. </el-form-item>
  517. </el-form>
  518. </div>
  519. </el-dialog>
  520. </div>
  521. </template>
  522. <script>
  523. import ThreeModel1 from "./component/ThreeModel1.vue";
  524. import PanelSand from "@com/coms/panel/panel-sand.vue";
  525. import PanelSandToolbar from "@com/coms/panel/panel-sand-toolbar.vue";
  526. import Weather from "./component/weather.vue";
  527. import StBack from "./component/st-back.vue";
  528. import Table from "@com/coms/table/table.vue";
  529. import RankTable from "./component/rank-table.vue";
  530. import Ppanel from "./component/p-panel.vue";
  531. import RadarPieChart from "@com/chart/pie/radar-pie-chart.vue";
  532. import DoubleLineChart from "@com/chart/line/double-line-chart.vue";
  533. import Col from "@com/coms/grid/col.vue";
  534. import Row from "@com/coms/grid/row.vue";
  535. import SvgIcon from "@com/coms/icon/svg-icon.vue";
  536. import hlsVideo from "./component/hls.vue";
  537. export default {
  538. // 名称
  539. name: "SandTable",
  540. // 使用组件
  541. components: {
  542. ThreeModel1,
  543. PanelSand,
  544. PanelSandToolbar,
  545. Weather,
  546. Table,
  547. RadarPieChart,
  548. StBack,
  549. RankTable,
  550. Ppanel,
  551. DoubleLineChart,
  552. Col,
  553. Row,
  554. SvgIcon,
  555. hlsVideo,
  556. },
  557. // 数据
  558. data() {
  559. const that = this;
  560. return {
  561. videoShow: true,
  562. showPanel: false,
  563. bjSwitch: false,
  564. warnSwitch: false,
  565. timmer1: null,
  566. showWeatherDialog: false,
  567. showTableDialog: false,
  568. showHealthDialog: false,
  569. showMainInfoDialog: false,
  570. weathercollapse: "",
  571. weatherChart: [
  572. {
  573. title: "温度",
  574. smooth: true,
  575. value: [],
  576. },
  577. {
  578. title: "湿度",
  579. smooth: true,
  580. value: [],
  581. },
  582. ],
  583. videoDialogClass: "modal animated a1 bounceIn",
  584. tableDialogClass: "modal animated a1 fadeInLeftBig",
  585. mainInfoDialogClass: "modal curModal animated a0 fadeInDownBig",
  586. mainInfo: [],
  587. peopleClass: "",
  588. timeStr: "",
  589. wpId: "0",
  590. tqmap1: {},
  591. tqmap5: [],
  592. gxkmap: {},
  593. tableItem: {},
  594. mapSource: {},
  595. videoArray1: [
  596. // [
  597. // { code: "NSS_FDC_ZK", class: "", switch: true },
  598. // { code: "NSS_FDC_ZK", class: "", switch: true },
  599. // ],
  600. // [
  601. // { code: "NSS_FDC_ZK", class: "", switch: true },
  602. // { code: "QS_FDC_ZK", class: "", switch: true },
  603. // ],
  604. // [
  605. // { code: "QS_FDC_ZK", class: "", switch: true },
  606. // { code: "QS_FDC_ZK", class: "", switch: true },
  607. // ],
  608. [
  609. { code: "SBQ_FDC_SC", class: "", switch: true },
  610. { code: "NSS_FDC_SC", class: "", switch: true },
  611. ],
  612. [
  613. { code: "QS_FDC_SC", class: "", switch: true },
  614. { code: "MHS_FDC_SC", class: "", switch: true },
  615. ],
  616. [
  617. { code: "XS_FDC_SC", class: "", switch: true },
  618. { code: "PL_GDC_SC", class: "", switch: true },
  619. ],
  620. ],
  621. videoArray: [
  622. [
  623. {
  624. url: "http://192.168.10.10:9984/ws.html",
  625. token: "?token=SBQ_FDC_SC&autoplay=true",
  626. class: "",
  627. switch: true,
  628. },
  629. {
  630. url: "http://192.168.10.10:9984/ws.html",
  631. token: "?token=NSS_FDC_SC&autoplay=true",
  632. class: "",
  633. switch: true,
  634. },
  635. ],
  636. [
  637. {
  638. url: "http://192.168.10.10:9984/ws.html",
  639. token: "?token=QS_FDC_SC&autoplay=true",
  640. class: "",
  641. switch: true,
  642. },
  643. {
  644. url: "http://192.168.10.10:9984/ws.html",
  645. token: "?token=MHS_FDC_SC&autoplay=true",
  646. class: "",
  647. switch: true,
  648. },
  649. ],
  650. [
  651. {
  652. url: "http://192.168.10.10:9984/ws.html",
  653. token: "?token=XS_FDC_SC&autoplay=true",
  654. class: "",
  655. switch: true,
  656. },
  657. {
  658. url: "http://192.168.10.10:9984/ws.html",
  659. token: "?token=PL_GDC_SC&autoplay=true",
  660. class: "",
  661. switch: true,
  662. },
  663. ],
  664. ],
  665. showVideoDialog: false,
  666. dialogVideoUrl: "",
  667. warnChartData: [],
  668. bjChartData: [],
  669. ForecastPower: [
  670. {
  671. name: "今日预测电量",
  672. value: 103.62,
  673. total: 150,
  674. },
  675. {
  676. name: "月预测发电量",
  677. value: 98.62,
  678. total: 100,
  679. },
  680. ],
  681. workDataIndex: 0,
  682. workData: {
  683. column: [
  684. {
  685. name: "人员",
  686. field: "laborname",
  687. is_num: false,
  688. is_light: false,
  689. click(e, row) {
  690. that.changePeople(row.index);
  691. },
  692. },
  693. {
  694. name: "职务",
  695. field: "jobcode",
  696. is_num: false,
  697. is_light: false,
  698. click(e, row) {
  699. that.changePeople(row.index);
  700. },
  701. },
  702. {
  703. name: "开始时间",
  704. field: "starttime",
  705. width: "150px",
  706. is_num: false,
  707. is_light: false,
  708. click(e, row) {
  709. that.changePeople(row.index);
  710. },
  711. },
  712. {
  713. name: "原因",
  714. field: "problem",
  715. is_num: false,
  716. is_light: false,
  717. click(e, row) {
  718. that.changePeople(row.index);
  719. },
  720. },
  721. ],
  722. data: [],
  723. },
  724. sels: {
  725. column: [
  726. {
  727. name: "风机编号",
  728. field: "windPowerStationId",
  729. },
  730. {
  731. name: "停机时间",
  732. field: "stopTime",
  733. width: "120px",
  734. },
  735. {
  736. name: "停机时长",
  737. field: "stopHours",
  738. },
  739. ],
  740. data: [],
  741. },
  742. rmls: {
  743. column: [
  744. {
  745. name: "风机编号",
  746. field: "wtId",
  747. },
  748. {
  749. name: "推荐时间",
  750. field: "recodedate",
  751. width: "120px",
  752. },
  753. {
  754. name: "类型",
  755. field: "operation",
  756. },
  757. ],
  758. data: [],
  759. },
  760. };
  761. },
  762. // 函数
  763. methods: {
  764. openWeatherDialog() {
  765. this.showWeatherDialog = true;
  766. },
  767. openVideoDialog(item) {
  768. if (item.url && item.token) {
  769. this.dialogVideoUrl = item.url + item.token;
  770. this.showVideoDialog = true;
  771. }
  772. },
  773. openVideoDialog1(item) {
  774. if (item.code) {
  775. this.dialogVideoUrl = item.code;
  776. this.showVideoDialog = true;
  777. }
  778. },
  779. getWtInfo() {
  780. let that = this;
  781. that.API.requestData({
  782. method: "POST",
  783. subUrl: "sandtable/findWtInfo",
  784. data: {
  785. wpId: that.wpId,
  786. },
  787. success(res) {
  788. res.data.tqmap5.ls.forEach((ele) => {
  789. ele.time = new Date(ele.time).formatDate("yyyy-MM-dd hh:mm");
  790. });
  791. const keys = ["wd", "sd"];
  792. let weatherChart = [
  793. {
  794. title: "温度",
  795. smooth: true,
  796. value: [],
  797. },
  798. {
  799. title: "湿度",
  800. smooth: true,
  801. value: [],
  802. },
  803. ];
  804. keys.forEach((key, keyIndex) => {
  805. res.data.tqmap5.ls.forEach((ele) => {
  806. weatherChart[keyIndex].value.push({
  807. text: ele.time,
  808. value: ele[key],
  809. });
  810. });
  811. });
  812. that.tqmap1 = res.data.tqmap1;
  813. that.tqmap5 = res.data.tqmap5.ls;
  814. res.data.sels.forEach((ele) => {
  815. ele.stopTime = new Date(ele.stopTime).formatDate(
  816. "yyyy-MM-dd hh:mm:ss"
  817. );
  818. ele.startTime = new Date(ele.stopTime).formatDate(
  819. "yyyy-MM-dd hh:mm:ss"
  820. );
  821. });
  822. res.data.rmls.forEach((ele) => {
  823. ele.recodedate = new Date(ele.recodedate).formatDate(
  824. "yyyy-MM-dd hh:mm:ss"
  825. );
  826. });
  827. that.sels.data = res.data.sels;
  828. that.rmls.data = res.data.rmls;
  829. that.gxkmap = res.data.gxkmap;
  830. that.weatherChart = weatherChart;
  831. },
  832. });
  833. },
  834. // 获取中部地图数据
  835. getWpHealthInfo() {
  836. let that = this;
  837. that.API.requestData({
  838. method: "POST",
  839. subUrl: "sandtable/judgeWpHealth",
  840. data: {
  841. wpId: that.wpId,
  842. },
  843. success(res) {
  844. that.mapSource = res.data;
  845. },
  846. });
  847. },
  848. // 获取报警玫瑰图
  849. getWarnMGT() {
  850. let that = this;
  851. that.API.requestData({
  852. method: "GET",
  853. baseURL: "http://192.168.1.18:8075/",
  854. subUrl: "alarm/count/query/alltotal",
  855. data: {
  856. stationid: that.wpId,
  857. },
  858. success(res) {
  859. let warnChartData = [];
  860. for (let key in res.data) {
  861. const ele = res.data[key];
  862. warnChartData.push({
  863. value: ele.count,
  864. name: ele.relatePartsText,
  865. });
  866. }
  867. that.warnChartData = warnChartData;
  868. },
  869. });
  870. },
  871. // 获取故障玫瑰图
  872. getStopMGT() {
  873. let that = this;
  874. that.API.requestData({
  875. method: "GET",
  876. baseURL: "http://192.168.1.18:8075/",
  877. subUrl: "shutdown/count/alltotal",
  878. data: {
  879. stId: that.wpId,
  880. },
  881. success(res) {
  882. let warnChartData = [];
  883. for (let key in res.data) {
  884. const ele = res.data[key];
  885. warnChartData.push({
  886. value: ele.count,
  887. name: ele.type,
  888. });
  889. }
  890. that.warnChartData = warnChartData;
  891. },
  892. });
  893. },
  894. // 获取库存玫瑰图
  895. getRepertoryMGT() {
  896. let that = this;
  897. that.API.requestData({
  898. method: "GET",
  899. baseURL: "http://192.168.1.18:9988/",
  900. subUrl: "inventory/groupcount",
  901. data: {
  902. stId: that.wpId,
  903. },
  904. success(res) {
  905. let bjChartData = [];
  906. for (let key in res.data) {
  907. const ele = res.data[key];
  908. bjChartData.push({
  909. value: ele.curbal,
  910. name: ele.description,
  911. });
  912. }
  913. that.bjChartData = bjChartData;
  914. },
  915. });
  916. },
  917. // 获取记录玫瑰图
  918. getRecordMGT() {
  919. let that = this;
  920. that.API.requestData({
  921. method: "GET",
  922. baseURL: "http://192.168.1.18:9988/",
  923. subUrl: "equoperationrecord/equupdatecount",
  924. data: {
  925. stId: that.wpId,
  926. },
  927. success(res) {
  928. let bjChartData = [];
  929. for (let key in res.data) {
  930. const ele = res.data[key];
  931. bjChartData.push({
  932. value: ele.count,
  933. name: ele.description,
  934. });
  935. }
  936. that.bjChartData = bjChartData;
  937. },
  938. });
  939. },
  940. // 获取中部地图数据
  941. getTop4Info() {
  942. let that = this;
  943. that.API.requestData({
  944. method: "GET",
  945. baseURL: "http://192.168.1.18:9988/",
  946. subUrl: "equoperationrecord/top4",
  947. data: {
  948. stId: that.wpId,
  949. },
  950. success(res) {
  951. res.data.forEach((ele, index) => {
  952. ele.index = index;
  953. ele.jobcode = ele.jobcode || "------";
  954. });
  955. that.workData.data = res.data;
  956. },
  957. });
  958. },
  959. // 获取主要指标
  960. getWpMainInfo() {
  961. let that = this;
  962. that.API.requestData({
  963. method: "GET",
  964. baseURL: "http://10.155.32.4:8034/",
  965. subUrl: "benchmark/zyzb",
  966. data: {
  967. windPowerStation: that.wpId,
  968. },
  969. success(res) {
  970. that.mainInfo = res.data;
  971. that.showMainInfoDialog = true;
  972. },
  973. });
  974. },
  975. clickStopRow(row) {
  976. this.tableItem = row;
  977. this.showTableDialog = true;
  978. },
  979. clickHealthRow(row) {
  980. this.tableItem = row;
  981. this.showHealthDialog = true;
  982. },
  983. delaylyFn(time, fn) {
  984. setTimeout(() => {
  985. fn();
  986. }, time);
  987. },
  988. riseNumber(number) {
  989. // if (number < 0) {
  990. // return (number - number * 2) / 100;
  991. // } else {
  992. // return number / 100;
  993. // }
  994. return number / 100;
  995. },
  996. // 切换人员展示
  997. changePeople(index) {
  998. if (!this.peopleAnmLock && this.workDataIndex !== index) {
  999. this.peopleAnmLock = true;
  1000. this.peopleClass = "fadeOutRight";
  1001. setTimeout(() => {
  1002. this.workDataIndex = index;
  1003. this.peopleClass = "fadeInRight";
  1004. this.peopleAnmLock = false;
  1005. }, 150);
  1006. }
  1007. },
  1008. // 点击风场或者光伏
  1009. clickMapItem(videoArray, wpId) {
  1010. this.wpId = wpId;
  1011. // this.videoArray.forEach((pEle, pIndex) => {
  1012. // pEle.forEach((cEle, cIndex) => {
  1013. // setTimeout(() => {
  1014. // // 设置隐藏动画
  1015. // cEle.class = "animated a1 flipOutX";
  1016. // setTimeout(() => {
  1017. // // 修改 token
  1018. // cEle.token =
  1019. // "?token=" + videoArray[pIndex + cIndex] + "&autoplay=true";
  1020. // setTimeout(() => {
  1021. // // 设置显示动画
  1022. // cEle.class = "animated a1 flipInX";
  1023. // }, 150);
  1024. // }, 350);
  1025. // }, (pIndex + cIndex + pIndex) * 150);
  1026. // });
  1027. // });
  1028. this.videoArray1.forEach((pEle, pIndex) => {
  1029. pEle.forEach((cEle, cIndex) => {
  1030. setTimeout(() => {
  1031. // 设置隐藏动画
  1032. cEle.class = "animated a1 flipOutX";
  1033. setTimeout(() => {
  1034. // 修改 token
  1035. cEle.code = videoArray[pIndex + cIndex];
  1036. setTimeout(() => {
  1037. // 设置显示动画
  1038. cEle.class = "animated a1 flipInX";
  1039. }, 150);
  1040. }, 350);
  1041. }, (pIndex + cIndex + pIndex) * 150);
  1042. });
  1043. });
  1044. this.getWtInfo();
  1045. this.getWpHealthInfo();
  1046. this.getTop4Info();
  1047. this.getWarnMGT();
  1048. this.getRepertoryMGT();
  1049. this.getWpMainInfo();
  1050. },
  1051. // 页面跳转
  1052. jumpUrl(url) {
  1053. this.$router.push(url);
  1054. },
  1055. when() {
  1056. this.showPanel = true;
  1057. },
  1058. changeBjSwitch() {
  1059. this.bjSwitch = !this.bjSwitch;
  1060. if (this.bjSwitch) {
  1061. this.getRecordMGT();
  1062. } else {
  1063. this.getRepertoryMGT();
  1064. }
  1065. },
  1066. changeWarnSwitch() {
  1067. this.warnSwitch = !this.warnSwitch;
  1068. if (this.warnSwitch) {
  1069. this.getStopMGT();
  1070. } else {
  1071. this.getWarnMGT();
  1072. }
  1073. },
  1074. },
  1075. // 生命周期钩子
  1076. beforeCreate() {
  1077. // 创建前
  1078. },
  1079. created() {
  1080. this.getWtInfo();
  1081. this.getWpHealthInfo();
  1082. this.getTop4Info();
  1083. this.getWarnMGT();
  1084. this.getRepertoryMGT();
  1085. this.timeStr = new Date().formatDate("MM-dd hh:mm");
  1086. this.timmer1 = setInterval(() => {
  1087. this.timeStr = new Date().formatDate("MM-dd hh:mm");
  1088. });
  1089. },
  1090. beforeMount() {
  1091. // 渲染前
  1092. },
  1093. mounted() {
  1094. // 渲染后
  1095. },
  1096. beforeUpdate() {
  1097. // 数据更新前
  1098. },
  1099. updated() {
  1100. // 数据更新后
  1101. },
  1102. unmounted() {
  1103. clearInterval(this.timmer1);
  1104. this.timmer1 = null;
  1105. },
  1106. };
  1107. </script>
  1108. <style lang="less">
  1109. .sand-table {
  1110. width: 100%;
  1111. height: 91.667vh;
  1112. position: relative;
  1113. .i3dback {
  1114. position: fixed;
  1115. z-index: -1;
  1116. width: 100vw;
  1117. height: 100vh;
  1118. top: 0;
  1119. left: 0;
  1120. }
  1121. .i3dcloud {
  1122. position: absolute;
  1123. z-index: 2;
  1124. width: 100vw;
  1125. height: 100vh;
  1126. top: 0;
  1127. left: 0;
  1128. }
  1129. .left-panel {
  1130. width: 360px;
  1131. }
  1132. .right-panel {
  1133. width: 36.852vh;
  1134. }
  1135. .three-model-layer {
  1136. position: absolute;
  1137. width: 100%;
  1138. height: 100%;
  1139. z-index: 1;
  1140. }
  1141. .sand-table-left {
  1142. position: absolute;
  1143. left: 0;
  1144. top: 0;
  1145. z-index: 2;
  1146. }
  1147. .sand-table-right {
  1148. position: absolute;
  1149. right: 0;
  1150. top: 0;
  1151. z-index: 2;
  1152. }
  1153. .sand-table-bottom {
  1154. position: absolute;
  1155. bottom: 0;
  1156. z-index: 2;
  1157. display: flex;
  1158. transform: 0.2s;
  1159. .stb-p {
  1160. margin-left: 0.926vh;
  1161. }
  1162. }
  1163. .pre-img-box {
  1164. display: flex;
  1165. align-items: center;
  1166. justify-content: center;
  1167. margin-top: 0.556vh;
  1168. padding: 0;
  1169. position: relative;
  1170. cursor: pointer;
  1171. .sand-table-bottom {
  1172. position: absolute;
  1173. bottom: 0;
  1174. z-index: 2;
  1175. display: flex;
  1176. transition: 0.2s;
  1177. }
  1178. .mask {
  1179. position: absolute;
  1180. left: 0;
  1181. top: 0;
  1182. width: 100%;
  1183. height: 100%;
  1184. z-index: 5;
  1185. }
  1186. .pre-img {
  1187. position: relative;
  1188. width: 95%;
  1189. height: 8.657vh;
  1190. z-index: 4;
  1191. }
  1192. }
  1193. .person-info-box {
  1194. display: flex;
  1195. .header {
  1196. width: 75px;
  1197. }
  1198. }
  1199. .table {
  1200. width: calc(100% + 2.963vh);
  1201. margin-left: -1.481vh;
  1202. margin-bottom: -1.481vh;
  1203. tr {
  1204. cursor: pointer;
  1205. }
  1206. .com-table thead tr th,
  1207. .com-table tr td {
  1208. padding: 0.556vh 0;
  1209. color: #fff;
  1210. }
  1211. }
  1212. .animated.a0 {
  1213. animation-duration: 0.35s;
  1214. }
  1215. .animated.a1 {
  1216. animation-duration: 0.5s;
  1217. }
  1218. .el-overlay {
  1219. overflow: hidden;
  1220. }
  1221. }
  1222. #sandTable.sand-table .curModal .el-dialog__body {
  1223. max-height: 600px;
  1224. overflow-y: scroll;
  1225. }
  1226. .exchange {
  1227. cursor: pointer;
  1228. }
  1229. .weatherBox {
  1230. width: 100%;
  1231. display: flex;
  1232. justify-content: space-around;
  1233. align-items: center;
  1234. .l,
  1235. .r {
  1236. width: 48%;
  1237. height: 500px;
  1238. padding: 50px 0;
  1239. }
  1240. .el-collapse {
  1241. border-top: 1px solid #999;
  1242. }
  1243. .el-collapse-item .el-collapse-item__wrap {
  1244. border-bottom: 1px solid #999;
  1245. }
  1246. .el-collapse-item__content {
  1247. background: rgba(18, 29, 28, 1);
  1248. color: rgba(255, 255, 255, 0.75);
  1249. padding: 20px;
  1250. }
  1251. .el-collapse-item__header {
  1252. background: rgb(18, 29, 28);
  1253. border-bottom: 1px solid #999;
  1254. color: rgba(255, 255, 255, 0.75);
  1255. }
  1256. .el-card__header,
  1257. .el-collapse,
  1258. .el-collapse-item__header {
  1259. border-bottom: 1px solid #999;
  1260. }
  1261. .collapseItemTitle {
  1262. display: flex;
  1263. justify-content: space-between;
  1264. align-items: center;
  1265. width: 100%;
  1266. .svg {
  1267. width: 20px;
  1268. height: 20px;
  1269. }
  1270. .info {
  1271. margin-left: 4px;
  1272. }
  1273. .otherWea {
  1274. margin-right: 10px;
  1275. }
  1276. }
  1277. .other-info {
  1278. text-align: center;
  1279. font-size: @fontsize-s;
  1280. .text {
  1281. color: @font-color;
  1282. font-size: 12px;
  1283. }
  1284. .value {
  1285. margin: 0.741vh 0 0 0;
  1286. }
  1287. .other-icon {
  1288. margin: 0 auto;
  1289. }
  1290. }
  1291. }
  1292. .videoBoxiframe {
  1293. border: none;
  1294. overflow: hidden;
  1295. cursor: pointer;
  1296. }
  1297. .modal {
  1298. .dialogTitle {
  1299. position: relative;
  1300. }
  1301. .jumpBtn {
  1302. position: absolute;
  1303. right: 30px;
  1304. top: 8px;
  1305. cursor: pointer;
  1306. font-size: 20px;
  1307. }
  1308. .el-divider__text {
  1309. background: rgb(17, 28, 27);
  1310. color: #b3bdc0;
  1311. }
  1312. .el-divider {
  1313. background: #b3bdc0;
  1314. }
  1315. animation-duration: 0;
  1316. @keyframes dialog-fade-in {
  1317. 0% {
  1318. transform: translate3d(-1000%, -1000%, 0);
  1319. opacity: 0;
  1320. }
  1321. 100% {
  1322. transform: translate3d(-1000%, -1000%, 0);
  1323. opacity: 1;
  1324. }
  1325. }
  1326. @keyframes dialog-fade-out {
  1327. 0% {
  1328. // transform: translate3d(0, 0, 0);
  1329. transform: translate3d(-1000%, -1000%, 0);
  1330. opacity: 1;
  1331. }
  1332. 100% {
  1333. // transform: translate3d(0, -100%, 0);
  1334. transform: translate3d(-1000%, -1000%, 0);
  1335. opacity: 0;
  1336. }
  1337. }
  1338. }
  1339. </style>