power-benchmarking.vue 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473
  1. <template>
  2. <div class="power-benchmarking-page">
  3. <div class="static">
  4. <div class="static-main">
  5. <span class="dot top-left"></span>
  6. <span class="dot bottom-left"></span>
  7. <span class="dot top-rignt"></span>
  8. <span class="dot bottom-right"></span>
  9. <div class="icon">
  10. <i class="svg-icon svg-icon-balck">
  11. <svg-icon :svgid="'svg-flash'" />
  12. </i>
  13. </div>
  14. <div class="info">
  15. <div class="title">累计增发电量</div>
  16. <div class="value">{{ increasescapacity }}</div>
  17. <div class="unit">万kWh</div>
  18. </div>
  19. </div>
  20. <div
  21. class="static-items"
  22. :style="
  23. $store.state.themeName === 'dark'
  24. ? 'flex: 0 0 860px;transition: 0.2s;'
  25. : ''
  26. "
  27. >
  28. <div class="static-items-title">
  29. <i class="svg-icon svg-icon-green">
  30. <svg-icon :svgid="'svg-flash'" />
  31. </i>
  32. 理论电量平衡分析法
  33. </div>
  34. <div class="items">
  35. <div class="item" v-for="(item, index) of analyselist" :key="index">
  36. <div class="title">{{ item.name }}</div>
  37. <div class="value">{{ item.actual }}%</div>
  38. <div class="up-down">
  39. <div class="up-down-item">
  40. <span class="name">环</span>
  41. <span class="icon">
  42. <i
  43. class="svg-icon svg-icon-sm"
  44. :class="
  45. item.mom >= 0 ? 'svg-icon-green' : 'svg-icon-yellow'
  46. "
  47. >
  48. <svg-icon
  49. :svgid="
  50. item.mom >= 0 ? 'svg-arrow-up-1' : 'svg-arrow-dpwn-1'
  51. "
  52. />
  53. </i>
  54. </span>
  55. <span class="value">{{ item.mom }}%</span>
  56. </div>
  57. <div class="up-down-item">
  58. <span class="name">同</span>
  59. <span class="icon">
  60. <i
  61. class="svg-icon svg-icon-sm"
  62. :class="
  63. item.yoy >= 0 ? 'svg-icon-green' : 'svg-icon-yellow'
  64. "
  65. >
  66. <svg-icon
  67. :svgid="
  68. item.yoy >= 0 ? 'svg-arrow-up-1' : 'svg-arrow-dpwn-1'
  69. "
  70. />
  71. </i>
  72. </span>
  73. <span class="value">{{ item.yoy }}%</span>
  74. </div>
  75. </div>
  76. <div class="percent">
  77. <div class="percent-box">
  78. <div
  79. class="percent-bar"
  80. :style="{ width: Math.abs(item.expect) + '%' }"
  81. :class="item.expect >= 0 ? 'bg-green' : 'bg-yellow'"
  82. ></div>
  83. <div
  84. class="sj"
  85. :style="{ 'margin-left': Math.abs(item.expect) - 4 + '%' }"
  86. :class="item.expect >= 0 ? 'sj' : 'yj'"
  87. ></div>
  88. </div>
  89. <div class="value">{{ item.expect }}%</div>
  90. </div>
  91. </div>
  92. </div>
  93. </div>
  94. <div
  95. class="static-items"
  96. :style="
  97. $store.state.themeName === 'dark'
  98. ? 'flex: 0 0 430px;transition: 0.2s;'
  99. : ''
  100. "
  101. >
  102. <div class="static-items-title">
  103. <i class="svg-icon svg-icon-green">
  104. <svg-icon :svgid="'svg-flash'" />
  105. </i>
  106. 管理效率指标
  107. </div>
  108. <div class="items">
  109. <div class="item" v-for="(item, index) of managelist" :key="index">
  110. <div class="title">{{ item.name }}</div>
  111. <div class="value">{{ item.actual }}%</div>
  112. <div class="up-down">
  113. <div class="up-down-item">
  114. <span class="name">环</span>
  115. <span class="icon">
  116. <i
  117. class="svg-icon svg-icon-sm"
  118. :class="
  119. item.mom >= 0 ? 'svg-icon-green' : 'svg-icon-yellow'
  120. "
  121. >
  122. <svg-icon
  123. :svgid="
  124. item.mom >= 0 ? 'svg-arrow-up-1' : 'svg-arrow-dpwn-1'
  125. "
  126. />
  127. </i>
  128. </span>
  129. <span class="value">{{ item.mom }}%</span>
  130. </div>
  131. <div class="up-down-item">
  132. <span class="name">同</span>
  133. <span class="icon">
  134. <i
  135. class="svg-icon svg-icon-sm"
  136. :class="
  137. item.yoy >= 0 ? 'svg-icon-green' : 'svg-icon-yellow'
  138. "
  139. >
  140. <svg-icon
  141. :svgid="
  142. item.yoy >= 0 ? 'svg-arrow-up-1' : 'svg-arrow-dpwn-1'
  143. "
  144. />
  145. </i>
  146. </span>
  147. <span class="value">{{ item.yoy }}%</span>
  148. </div>
  149. </div>
  150. <div class="percent">
  151. <div class="percent-box">
  152. <div
  153. class="percent-bar"
  154. :style="{ width: Math.abs(item.expect) + '%' }"
  155. :class="item.expect >= 0 ? 'bg-green' : 'bg-yellow'"
  156. ></div>
  157. <div
  158. class="sj"
  159. :style="{ 'margin-left': Math.abs(item.expect) - 4 + '%' }"
  160. :class="item.expect >= 0 ? 'sj' : 'yj'"
  161. ></div>
  162. </div>
  163. <div class="value">{{ item.expect }}%</div>
  164. </div>
  165. </div>
  166. </div>
  167. </div>
  168. <div
  169. class="static-items"
  170. :style="
  171. $store.state.themeName === 'dark'
  172. ? 'flex: 0 0 430px;transition: 0.2s;'
  173. : ''
  174. "
  175. >
  176. <div class="static-items-title">
  177. <i class="svg-icon svg-icon-green">
  178. <svg-icon :svgid="'svg-flash'" />
  179. </i>
  180. 其它经济性指标
  181. </div>
  182. <div class="items">
  183. <div class="item" v-for="(item, index) of economiclist" :key="index">
  184. <div class="title">{{ item.name }}</div>
  185. <div class="value">{{ item.actual }}%</div>
  186. <div class="up-down">
  187. <div class="up-down-item">
  188. <span class="name">环</span>
  189. <span class="icon">
  190. <i
  191. class="svg-icon svg-icon-sm"
  192. :class="
  193. item.mom >= 0 ? 'svg-icon-green' : 'svg-icon-yellow'
  194. "
  195. >
  196. <svg-icon
  197. :svgid="
  198. item.mom >= 0 ? 'svg-arrow-up-1' : 'svg-arrow-dpwn-1'
  199. "
  200. />
  201. </i>
  202. </span>
  203. <span class="value">{{ item.mom }}%</span>
  204. </div>
  205. <div class="up-down-item">
  206. <span class="name">同</span>
  207. <span class="icon">
  208. <i
  209. class="svg-icon svg-icon-sm"
  210. :class="
  211. item.yoy >= 0 ? 'svg-icon-green' : 'svg-icon-yellow'
  212. "
  213. >
  214. <svg-icon
  215. :svgid="
  216. item.yoy >= 0 ? 'svg-arrow-up-1' : 'svg-arrow-dpwn-1'
  217. "
  218. />
  219. </i>
  220. </span>
  221. <span class="value">{{ item.yoy }}%</span>
  222. </div>
  223. </div>
  224. <div class="percent">
  225. <div class="percent-box">
  226. <div
  227. class="percent-bar"
  228. :style="{ width: Math.abs(item.expect) + '%' }"
  229. :class="item.expect >= 0 ? 'bg-green' : 'bg-yellow'"
  230. ></div>
  231. <div
  232. class="sj"
  233. :style="{ 'margin-left': Math.abs(item.expect) - 4 + '%' }"
  234. :class="item.expect >= 0 ? 'sj' : 'yj'"
  235. ></div>
  236. </div>
  237. <div class="value">{{ item.expect }}%</div>
  238. </div>
  239. </div>
  240. </div>
  241. </div>
  242. </div>
  243. <div class="top">
  244. <div class="top-left">
  245. <div class="top-left-header">
  246. <div class="header-left">
  247. <div class="selecttion">
  248. <div
  249. class="item"
  250. :class="{ active: selecttionIndex == 0 }"
  251. @click="selectionClick(0)"
  252. >
  253. </div>
  254. <!-- <div class="item" :class="{ active: selecttionIndex == 1 }" @click="selectionClick(1)">周</div> -->
  255. <div
  256. class="item"
  257. :class="{ active: selecttionIndex == 2 }"
  258. @click="selectionClick(2)"
  259. >
  260. </div>
  261. <!-- <div class="item" :class="{ active: selecttionIndex == 3 }" @click="selectionClick(3)">季</div> -->
  262. <div
  263. class="item"
  264. :class="{ active: selecttionIndex == 4 }"
  265. @click="selectionClick(4)"
  266. >
  267. </div>
  268. </div>
  269. <!-- <div class="query">
  270. <div class="query-items">
  271. <div class="query-item">
  272. <div class="lable">风场:</div>
  273. <div class="search-input">
  274. <el-cascader :options="cascader.options" :props="cascader.props" collapse-tags clearable></el-cascader>
  275. </div>
  276. </div>
  277. </div>
  278. <div class="query-items">
  279. <div class="query-item">
  280. <div class="lable">风场:</div>
  281. <div class="search-input">
  282. <el-cascader :options="cascader.options" :props="cascader.props" collapse-tags clearable></el-cascader>
  283. </div>
  284. </div>
  285. </div>
  286. </div> -->
  287. </div>
  288. <div class="header-right">
  289. <div
  290. class="right-btn"
  291. :class="{ active: btnIndex == 0 }"
  292. @click="rightBtnClick(0)"
  293. >
  294. 风电
  295. </div>
  296. <!-- <div class="right-btn" :class="{ active: btnIndex == 1 }" @click="rightBtnClick(1)">光伏</div> -->
  297. <span class="right-btn">光伏</span>
  298. </div>
  299. </div>
  300. <group-table
  301. :customClass="'table'"
  302. :data="eltableData"
  303. :height="'370px'"
  304. :elPaggingProps="null"
  305. @headerClick="headerClick"
  306. ref="jjyxTableRef"
  307. ></group-table>
  308. </div>
  309. <div class="top-right">
  310. <div class="rank-title">
  311. <div class="border top-left"></div>
  312. <div class="border top-right"></div>
  313. <div class="border bottom-left"></div>
  314. <div class="border bottom-right"></div>
  315. 排行榜
  316. </div>
  317. <div class="rank-block"></div>
  318. <group-table
  319. :customClass="'rank-table'"
  320. :data="greenTable"
  321. :height="'357px'"
  322. :elPaggingProps="null"
  323. >
  324. <template v-slot:rank="scope">
  325. <div class="rank-index" :class="'index-' + scope.row.rank">
  326. {{ scope.row.rank }}
  327. </div>
  328. </template>
  329. </group-table>
  330. </div>
  331. </div>
  332. <div class="bottom">
  333. <panel :title="'指标分析'">
  334. <multiple-bar-chart
  335. :list="barData"
  336. :height="'calc(100vh - 720px)'"
  337. :units="unit"
  338. />
  339. </panel>
  340. </div>
  341. </div>
  342. </template>
  343. <script>
  344. import MultipleBarChart from "../../components/chart/bar/multiple-bar-chart.vue";
  345. import SvgIcon from "../../components/coms/icon/svg-icon.vue";
  346. import Panel from "../../components/coms/panel/panel.vue";
  347. import groupTable from "../../components/coms/table/group-table.vue";
  348. export default {
  349. components: { groupTable, Panel, MultipleBarChart, SvgIcon },
  350. data() {
  351. return {
  352. selecttionIndex: 2,
  353. btnIndex: 0,
  354. increasescapacity: 0, //增发电量
  355. analyselist: [
  356. //理论平衡分析法
  357. { name: "风能利用率", label: "windenergy" },
  358. { name: "非计划检修损失率", label: "failurelossrate" },
  359. { name: "计划检修损失率", label: "mainlossrate" },
  360. { name: "限电损失率", label: "powerlossrate" },
  361. { name: "受累损失率", label: "daynhcfdl" },
  362. { name: "性能损失率", label: "performancelossrate" },
  363. ],
  364. managelist: [
  365. //管理效率指标
  366. { name: "复位及时率", label: "resettimelyrate" },
  367. { name: "状态转换率", label: "statetransitionrate" },
  368. { name: "消缺及时率", label: "eliminationrate" },
  369. ],
  370. economiclist: [
  371. //经济指标
  372. { name: "综合厂用电率", label: "comprehensiverate" },
  373. { name: "AGC曲线追随率", label: "agccurvefollowing" },
  374. { name: "风功率预测准确率", label: "windpoweraccuracy" },
  375. ],
  376. eltableData: {
  377. column: [
  378. {
  379. name: "",
  380. child: [
  381. {
  382. name: "区域公司",
  383. field: "name",
  384. width: 80,
  385. },
  386. {
  387. name: "评分",
  388. field: "mark",
  389. width: 55,
  390. },
  391. ],
  392. },
  393. {
  394. name: "基础指标",
  395. child: [
  396. {
  397. name: "装机容量(MW)",
  398. field: "capacity",
  399. width: 60,
  400. },
  401. {
  402. name: "在运台数(台)",
  403. field: "units",
  404. width: 60,
  405. },
  406. {
  407. name: "理论电量(万kWh)",
  408. field: "theoreticalpower",
  409. width: 70,
  410. },
  411. {
  412. name: "实际发电量(万kWh)",
  413. field: "actualpower",
  414. width: 70,
  415. },
  416. {
  417. name: "故障损失电量(万kWh)",
  418. field: "daynhgzssdl",
  419. width: 65,
  420. },
  421. {
  422. name: "维护损失电量(万kWh)",
  423. field: "daynhwhssdl",
  424. width: 60,
  425. },
  426. {
  427. name: "限电损失电量(万kWh)",
  428. field: "daynhxdssdl",
  429. width: 65,
  430. },
  431. {
  432. name: "受累损失电量(万kWh)",
  433. field: "daynhcfdl",
  434. width: 55,
  435. },
  436. {
  437. name: "性能损失电量(万kWh)",
  438. field: "daynhqfdl",
  439. width: 65,
  440. },
  441. ],
  442. },
  443. {
  444. name: "经济指标",
  445. child: [
  446. {
  447. name: "风能利用率(%)",
  448. field: "windenergy",
  449. width: this.$store.state.themeName === "dark" ? 55 : 50,
  450. },
  451. {
  452. name: "限电损失率(%)",
  453. field: "powerlossrate",
  454. width: this.$store.state.themeName === "dark" ? 55 : 50,
  455. },
  456. {
  457. name: "性能损失率(%)",
  458. field: "performancelossrate",
  459. width: this.$store.state.themeName === "dark" ? 55 : 50,
  460. },
  461. {
  462. name: "综合厂用电率(%)",
  463. field: "comprehensiverate",
  464. width: this.$store.state.themeName === "dark" ? 55 : 50,
  465. },
  466. {
  467. name: "设备利用小时(小时)",
  468. field: "utilizationhours",
  469. width: this.$store.state.themeName === "dark" ? 55 : 50,
  470. },
  471. {
  472. name: "风功率预测准确率(%)",
  473. field: "windpoweraccuracy",
  474. width: this.$store.state.themeName === "dark" ? 55 : 50,
  475. },
  476. {
  477. name: "AGC曲线跟随率(%)",
  478. field: "agccurvefollowing",
  479. width: this.$store.state.themeName === "dark" ? 55 : 50,
  480. },
  481. ],
  482. },
  483. {
  484. name: "设备指标",
  485. child: [
  486. {
  487. name: "MTBF(小时)",
  488. field: "mtbf",
  489. width: 55,
  490. },
  491. {
  492. name: "MTTF(小时)",
  493. field: "mttf",
  494. width: 55,
  495. },
  496. {
  497. name: "设备可利用率 (%)",
  498. field: "availability",
  499. width: 55,
  500. },
  501. {
  502. name: "等效可用系数 (%)",
  503. field: "availabilityfactor",
  504. width: 55,
  505. },
  506. {
  507. name: "非计划检修损失率(%)",
  508. field: "failurelossrate",
  509. width: 55,
  510. },
  511. ],
  512. },
  513. {
  514. name: "管理效率指标",
  515. child: [
  516. {
  517. name: "计划检修损失率(%)",
  518. field: "mainlossrate",
  519. width: 53,
  520. },
  521. {
  522. name: "MTTR(小时)",
  523. field: "mttr",
  524. width: 53,
  525. },
  526. {
  527. name: "隐患发现准确率(%)",
  528. field: "hiddentimely",
  529. width: 53,
  530. },
  531. {
  532. name: "复位及时率(%)",
  533. field: "resettimelyrate",
  534. width: 53,
  535. },
  536. {
  537. name: "状态转换率(%)",
  538. field: "statetransitionrate",
  539. width: 53,
  540. },
  541. {
  542. name: "消缺及时率(%)",
  543. field: "eliminationrate",
  544. width: 53,
  545. },
  546. ],
  547. },
  548. ],
  549. data: [],
  550. },
  551. eltableDataBackup: {},
  552. greenTable: {
  553. column: [
  554. {
  555. name: "排名",
  556. field: "rank",
  557. width: 50,
  558. slot: true,
  559. },
  560. {
  561. name: "名称",
  562. field: "name",
  563. width: 70,
  564. },
  565. {
  566. name: "指标项",
  567. child: [
  568. {
  569. name: "风能利用率(%)",
  570. field: "v1",
  571. width: 80,
  572. },
  573. ],
  574. },
  575. ],
  576. data: [],
  577. },
  578. barData: [],
  579. unit: ["万kWh", ""], //单位
  580. };
  581. },
  582. created() {
  583. this.requestDataTable("月");
  584. this.requestDataTop("月");
  585. },
  586. mounted() {
  587. this.$nextTick(() => {
  588. this.eltableDataBackup = this.BASE.deepCopy(this.eltableData);
  589. this.resetTableSize(this.$store.state.themeName);
  590. });
  591. },
  592. methods: {
  593. selectionClick(index) {
  594. this.selecttionIndex = index;
  595. switch (index) {
  596. case 0:
  597. this.requestDataTable("日");
  598. this.requestDataTop("日");
  599. break;
  600. case 1:
  601. this.requestDataTable("周");
  602. this.requestDataTop("周");
  603. break;
  604. case 2:
  605. this.requestDataTable("月");
  606. this.requestDataTop("月");
  607. break;
  608. case 3:
  609. this.requestDataTable("季");
  610. this.requestDataTop("季");
  611. break;
  612. case 4:
  613. this.requestDataTable("年");
  614. this.requestDataTop("年");
  615. break;
  616. }
  617. },
  618. headerClick(param) {
  619. // 点击一级标题事件
  620. if (param.level == 1) {
  621. if (param.col.name != "" && param.col.name != "基础指标") {
  622. this.echartData(param.col.child);
  623. this.unit = ["百分比(%)", "小时"];
  624. }
  625. if (param.col.name != "" && param.col.name == "基础指标") {
  626. this.echartData(param.col.child.slice(3));
  627. this.unit = ["百分比(%)", ""];
  628. }
  629. }
  630. if (param.level == 2 && param.col.field != "区域公司") {
  631. this.setRank(param.col.field, param.col.name);
  632. }
  633. },
  634. rightBtnClick(index) {
  635. this.btnIndex = index;
  636. },
  637. // 表格数据
  638. requestDataTable(timetype) {
  639. let that = this;
  640. this.API.requestData({
  641. method: "GET",
  642. baseURL: "http://10.155.32.4:9001/",
  643. subUrl: "benchmarking/dbmainbottom",
  644. data: {
  645. timetype: timetype,
  646. foreigntype: "风电",
  647. },
  648. success(res) {
  649. if (res.code == 200) {
  650. res.data.forEach((item) => {
  651. if (item.foreignkeyid === "SBQ_FDC") item.name = "石板泉";
  652. if (item.foreignkeyid === "MHS_FDC") item.name = "麻黄山";
  653. if (item.foreignkeyid === "NSS_FDC") item.name = "牛首山";
  654. if (item.foreignkeyid === "XS_FDC") item.name = "香山";
  655. if (item.foreignkeyid === "QS_FDC") item.name = "青山";
  656. item.mark = that.filter(item.mark);
  657. item.theoreticalpower = that.filter(item.theoreticalpower);
  658. item.actualpower = that.filter(item.actualpower);
  659. item.daynhgzssdl = that.filter(item.daynhgzssdl);
  660. item.daynhwhssdl = that.filter(item.daynhwhssdl);
  661. item.daynhxdssdl = that.filter(item.daynhxdssdl);
  662. item.daynhcfdl = that.filter(item.daynhcfdl);
  663. item.daynhqfdl = that.filter(item.daynhqfdl);
  664. item.windenergy = that.filter(item.windenergy);
  665. item.powerlossrate = that.filter(item.powerlossrate);
  666. item.performancelossrate = that.filter(item.performancelossrate);
  667. item.comprehensiverate = that.filter(item.comprehensiverate);
  668. item.utilizationhours = that.filter(item.utilizationhours);
  669. item.windpoweraccuracy = that.filter(item.windpoweraccuracy);
  670. item.agccurvefollowing = that.filter(item.agccurvefollowing);
  671. item.mtbf = that.filter(item.mtbf);
  672. item.mttf = that.filter(item.mttf);
  673. item.availability = that.filter(item.availability);
  674. item.availabilityfactor = that.filter(item.availabilityfactor);
  675. item.failurelossrate = that.filter(item.failurelossrate);
  676. item.mainlossrate = that.filter(item.mainlossrate);
  677. item.mttr = that.filter(item.mttr);
  678. item.hiddentimely = that.filter(item.hiddentimely);
  679. item.resettimelyrate = that.filter(item.resettimelyrate);
  680. item.statetransitionrate = that.filter(item.statetransitionrate);
  681. item.eliminationrate = that.filter(item.eliminationrate);
  682. });
  683. // 合计列
  684. let item = res.data;
  685. let obj = {
  686. name: "合计",
  687. mark: that.filter(
  688. (Number(item[0].mark) +
  689. Number(item[1].mark) +
  690. Number(item[2].mark) +
  691. Number(item[3].mark)) /
  692. 4
  693. ),
  694. capacity: that.filter(
  695. Number(item[0].capacity) +
  696. Number(item[1].capacity) +
  697. Number(item[2].capacity) +
  698. Number(item[3].capacity)
  699. ),
  700. units: that.filter(
  701. Number(item[0].units) +
  702. Number(item[1].units) +
  703. Number(item[2].units) +
  704. Number(item[3].units)
  705. ),
  706. theoreticalpower: that.filter(
  707. Number(item[0].theoreticalpower) +
  708. Number(item[1].theoreticalpower) +
  709. Number(item[2].theoreticalpower) +
  710. Number(item[3].theoreticalpower)
  711. ),
  712. actualpower: that.filter(
  713. Number(item[0].actualpower) +
  714. Number(item[1].actualpower) +
  715. Number(item[2].actualpower) +
  716. Number(item[3].actualpower)
  717. ),
  718. daynhgzssdl: that.filter(
  719. Number(item[0].daynhgzssdl) +
  720. Number(item[1].daynhgzssdl) +
  721. Number(item[2].daynhgzssdl) +
  722. Number(item[3].daynhgzssdl)
  723. ),
  724. daynhwhssdl: that.filter(
  725. Number(item[0].daynhwhssdl) +
  726. Number(item[1].daynhwhssdl) +
  727. Number(item[2].daynhwhssdl) +
  728. Number(item[3].daynhwhssdl)
  729. ),
  730. daynhxdssdl: that.filter(
  731. Number(item[0].daynhxdssdl) +
  732. Number(item[1].daynhxdssdl) +
  733. Number(item[2].daynhxdssdl) +
  734. Number(item[3].daynhxdssdl)
  735. ),
  736. daynhcfdl: that.filter(
  737. Number(item[0].daynhcfdl) +
  738. Number(item[1].daynhcfdl) +
  739. Number(item[2].daynhcfdl) +
  740. Number(item[3].daynhcfdl)
  741. ),
  742. daynhqfdl: that.filter(
  743. Number(item[0].daynhqfdl) +
  744. Number(item[1].daynhqfdl) +
  745. Number(item[2].daynhqfdl) +
  746. Number(item[3].daynhqfdl)
  747. ),
  748. windenergy: that.filter(
  749. (Number(item[0].windenergy) +
  750. Number(item[1].windenergy) +
  751. Number(item[2].windenergy) +
  752. Number(item[3].windenergy)) /
  753. 4
  754. ),
  755. powerlossrate: that.filter(
  756. (Number(item[0].powerlossrate) +
  757. Number(item[1].powerlossrate) +
  758. Number(item[2].powerlossrate) +
  759. Number(item[3].powerlossrate)) /
  760. 4
  761. ),
  762. performancelossrate: that.filter(
  763. (Number(item[0].performancelossrate) +
  764. Number(item[1].performancelossrate) +
  765. Number(item[2].performancelossrate) +
  766. Number(item[3].performancelossrate)) /
  767. 4
  768. ),
  769. comprehensiverate: that.filter(
  770. (Number(item[0].comprehensiverate) +
  771. Number(item[1].comprehensiverate) +
  772. Number(item[2].comprehensiverate) +
  773. Number(item[3].comprehensiverate)) /
  774. 4
  775. ),
  776. utilizationhours: that.filter(
  777. Number(item[0].utilizationhours) +
  778. Number(item[1].utilizationhours) +
  779. Number(item[2].utilizationhours) +
  780. Number(item[3].utilizationhours)
  781. ),
  782. windpoweraccuracy: that.filter(
  783. (Number(item[0].windpoweraccuracy) +
  784. Number(item[1].windpoweraccuracy) +
  785. Number(item[2].windpoweraccuracy) +
  786. Number(item[3].windpoweraccuracy)) /
  787. 4
  788. ),
  789. agccurvefollowing: that.filter(
  790. (Number(item[0].agccurvefollowing) +
  791. Number(item[1].agccurvefollowing) +
  792. Number(item[2].agccurvefollowing) +
  793. Number(item[3].agccurvefollowing)) /
  794. 4
  795. ),
  796. mtbf: that.filter(
  797. Number(item[0].mtbf) +
  798. Number(item[1].mtbf) +
  799. Number(item[2].mtbf) +
  800. Number(item[3].mtbf)
  801. ),
  802. mttf: that.filter(
  803. Number(item[0].mttf) +
  804. Number(item[1].mttf) +
  805. Number(item[2].mttf) +
  806. Number(item[3].mttf)
  807. ),
  808. availability: that.filter(
  809. (Number(item[0].availability) +
  810. Number(item[1].availability) +
  811. Number(item[2].availability) +
  812. Number(item[3].availability)) /
  813. 4
  814. ),
  815. availabilityfactor: that.filter(
  816. (Number(item[0].availabilityfactor) +
  817. Number(item[1].availabilityfactor) +
  818. Number(item[2].availabilityfactor) +
  819. Number(item[3].availabilityfactor)) /
  820. 4
  821. ),
  822. failurelossrate: that.filter(
  823. (Number(item[0].failurelossrate) +
  824. Number(item[1].failurelossrate) +
  825. Number(item[2].failurelossrate) +
  826. Number(item[3].failurelossrate)) /
  827. 4
  828. ),
  829. mainlossrate: that.filter(
  830. (Number(item[0].mainlossrate) +
  831. Number(item[1].mainlossrate) +
  832. Number(item[2].mainlossrate) +
  833. Number(item[3].mainlossrate)) /
  834. 4
  835. ),
  836. mttr: that.filter(
  837. Number(item[0].mttr) +
  838. Number(item[1].mttr) +
  839. Number(item[2].mttr) +
  840. Number(item[3].mttr)
  841. ),
  842. hiddentimely: that.filter(
  843. (Number(item[0].hiddentimely) +
  844. Number(item[1].hiddentimely) +
  845. Number(item[2].hiddentimely) +
  846. Number(item[3].hiddentimely)) /
  847. 4
  848. ),
  849. resettimelyrate: that.filter(
  850. (Number(item[0].resettimelyrate) +
  851. Number(item[1].resettimelyrate) +
  852. Number(item[2].resettimelyrate) +
  853. Number(item[3].resettimelyrate)) /
  854. 4
  855. ),
  856. statetransitionrate: that.filter(
  857. (Number(item[0].statetransitionrate) +
  858. Number(item[1].statetransitionrate) +
  859. Number(item[2].statetransitionrate) +
  860. Number(item[3].statetransitionrate)) /
  861. 4
  862. ),
  863. eliminationrate: that.filter(
  864. (Number(item[0].eliminationrate) +
  865. Number(item[1].eliminationrate) +
  866. Number(item[2].eliminationrate) +
  867. Number(item[3].eliminationrate)) /
  868. 4
  869. ),
  870. };
  871. item.push(obj);
  872. that.eltableData.data = res.data;
  873. that.setRank();
  874. that.echartData(that.eltableData.column[1].child.slice(3));
  875. }
  876. },
  877. });
  878. },
  879. // 顶部数据
  880. requestDataTop(timetype) {
  881. let that = this;
  882. this.API.requestData({
  883. method: "GET",
  884. baseURL: "http://10.155.32.4:9001/",
  885. subUrl: "benchmarking/dbmaintop",
  886. data: {
  887. timetype: timetype,
  888. foreigntype: "风电",
  889. },
  890. success(res) {
  891. if (res.code == 200) that.calculate(res.data);
  892. },
  893. });
  894. },
  895. // 左边的排序
  896. setRank(column, name) {
  897. if (column == undefined) {
  898. column = "actualpower";
  899. name = "实际发电量";
  900. }
  901. this.greenTable.data = [];
  902. let datas = Object.assign([], this.eltableData.data);
  903. let array = datas.slice(0, 5).sort(this.compare(column));
  904. for (var i = 0; i < array.length; i++) {
  905. let obj = {
  906. rank: i + 1,
  907. name: array[i].name,
  908. v1: array[i][column],
  909. };
  910. this.greenTable.data[i] = obj;
  911. }
  912. this.greenTable.column[2].child[0].name = name;
  913. },
  914. // 下面的echart图
  915. echartData(child) {
  916. let barData = [];
  917. let count = this.eltableData.data.length;
  918. for (let j = 0; j < child.length; j++) {
  919. let item = {
  920. title: child[j].name,
  921. yAxisIndex: child[j].name.indexOf("小时") == -1 ? 0 : 1,
  922. value: [],
  923. };
  924. for (let i = 0; i < count - 1; i++) {
  925. let obj = {
  926. text: this.eltableData.data[i].name,
  927. value: this.eltableData.data[i][child[j].field],
  928. };
  929. item.value.push(obj);
  930. }
  931. barData.push(item);
  932. }
  933. this.barData = barData;
  934. },
  935. // 对象排序
  936. compare(prop) {
  937. return function (obj1, obj2) {
  938. var val1 = obj1[prop];
  939. var val2 = obj2[prop];
  940. if (!isNaN(Number(val1)) && !isNaN(Number(val2))) {
  941. val1 = Number(val1);
  942. val2 = Number(val2);
  943. }
  944. return val1 > val2 ? -1 : val1 < val2 ? 1 : 0;
  945. };
  946. },
  947. // 同比环比计算
  948. calculate(array) {
  949. let shiji = {};
  950. let huanbi = {};
  951. let tongbi = {};
  952. let jizhun = {};
  953. array.forEach((item) => {
  954. if (item.foreignkeyid === "实际") shiji = item;
  955. if (item.foreignkeyid === "环比") huanbi = item;
  956. if (item.foreignkeyid === "同比") tongbi = item;
  957. if (item.foreignkeyid === "基准") jizhun = item;
  958. });
  959. this.increasescapacity = Math.abs(
  960. this.filter(jizhun.actualpower - shiji.actualpower)
  961. );
  962. // 理论电量平衡分析
  963. for (let item of this.analyselist) {
  964. let key = item.label;
  965. item.actual = this.filter(shiji[key]);
  966. item.mom = this.filter(shiji[key] - huanbi[key]); //环比
  967. item.yoy = this.filter(shiji[key] - tongbi[key]); //同比
  968. item.expect = this.filter(shiji[key] - jizhun[key]);
  969. }
  970. // 管理效率指标
  971. for (let item of this.managelist) {
  972. let key = item.label;
  973. item.actual = Math.abs(this.filter(shiji[key]));
  974. item.mom = Math.abs(this.filter(shiji[key] - huanbi[key])); //环比
  975. item.yoy = Math.abs(this.filter(shiji[key] - tongbi[key])); //同比
  976. item.expect = Math.abs(this.filter(shiji[key] - jizhun[key]));
  977. }
  978. // 经济指标
  979. for (let item of this.economiclist) {
  980. let key = item.label;
  981. item.actual = this.filter(shiji[key]);
  982. item.mom = this.filter(shiji[key] - huanbi[key]); //环比
  983. item.yoy = this.filter(shiji[key] - tongbi[key]); //同比
  984. item.expect = this.filter(shiji[key] - jizhun[key]);
  985. }
  986. },
  987. // 保留小数位l
  988. filter(num) {
  989. return num % 1 === 0 ? num : num.toFixed(1);
  990. },
  991. resetTableSize(themeName) {
  992. this.$nextTick(() => {
  993. this.eltableData.column.forEach((pEle, pIndex) => {
  994. pEle.child.forEach((cEle, cIndex) => {
  995. const width =
  996. this.eltableDataBackup.column[pIndex].child[cIndex].width;
  997. cEle.width = themeName === "dark" ? width : width - 1;
  998. });
  999. });
  1000. this.$refs?.jjyxTableRef?.$refs?.groupTable?.doLayout();
  1001. });
  1002. },
  1003. },
  1004. watch: {
  1005. "$store.state.themeName"(themeName) {
  1006. this.resetTableSize(themeName);
  1007. },
  1008. },
  1009. };
  1010. </script>
  1011. <style lang="less">
  1012. .power-benchmarking-page {
  1013. .static {
  1014. display: flex;
  1015. height: 162px;
  1016. margin-bottom: 8px;
  1017. .static-main {
  1018. position: relative;
  1019. flex: 0 0 150px;
  1020. height: 162px;
  1021. border: 1px solid fade(@green, 60);
  1022. padding: 8px;
  1023. background: fade(@gray, 20);
  1024. margin-right: 8px;
  1025. .dot {
  1026. position: absolute;
  1027. width: 3px;
  1028. height: 3px;
  1029. background: @green;
  1030. &.top-left {
  1031. top: 5px;
  1032. left: 5px;
  1033. }
  1034. &.bottom-left {
  1035. bottom: 5px;
  1036. left: 5px;
  1037. }
  1038. &.top-rignt {
  1039. top: 5px;
  1040. right: 5px;
  1041. }
  1042. &.bottom-right {
  1043. bottom: 5px;
  1044. right: 5px;
  1045. }
  1046. }
  1047. .icon {
  1048. height: 40px;
  1049. margin: 8px 0;
  1050. display: flex;
  1051. justify-content: center;
  1052. i {
  1053. width: 36px;
  1054. height: 36px;
  1055. padding: 2px;
  1056. background: @green;
  1057. border-radius: 100%;
  1058. border: 4px solid @gray;
  1059. svg {
  1060. width: 24px;
  1061. height: 24px;
  1062. use {
  1063. fill: #000;
  1064. }
  1065. }
  1066. }
  1067. }
  1068. .info {
  1069. text-align: center;
  1070. .title {
  1071. font-size: 18px;
  1072. margin-bottom: 12px;
  1073. }
  1074. .value {
  1075. font-size: 18px;
  1076. color: @green;
  1077. margin-bottom: 4px;
  1078. }
  1079. .unit {
  1080. padding: 0 8px;
  1081. text-align: right;
  1082. }
  1083. }
  1084. }
  1085. .static-items {
  1086. border: 1px solid fade(@gray, 60);
  1087. margin-right: 8px;
  1088. .static-items-title {
  1089. text-align: center;
  1090. line-height: 27px;
  1091. height: 27px;
  1092. display: flex;
  1093. justify-content: center;
  1094. align-items: center;
  1095. color: @green;
  1096. }
  1097. .items {
  1098. display: flex;
  1099. justify-content: space-between;
  1100. .item {
  1101. // flex: 0 0 138px;
  1102. width: 136px;
  1103. height: 133px;
  1104. margin-left: 8px;
  1105. background: fade(@gray, 20);
  1106. text-align: center;
  1107. padding: 8px;
  1108. & > .title {
  1109. font-size: 14px;
  1110. color: @gray-l;
  1111. }
  1112. & > .value {
  1113. font-family: @font-family-num;
  1114. margin: 8px 0;
  1115. }
  1116. & > .up-down {
  1117. display: flex;
  1118. justify-content: space-around;
  1119. margin: 15px 0;
  1120. font-size: xx-small;
  1121. .up-down-item {
  1122. flex: 1 0 auto;
  1123. display: flex;
  1124. align-items: center;
  1125. justify-content: space-around;
  1126. }
  1127. }
  1128. & > .percent {
  1129. display: flex;
  1130. .percent-box {
  1131. position: relative;
  1132. height: 10px;
  1133. border: 1px solid @gray;
  1134. margin-right: 8px;
  1135. width: calc(100% - 38px);
  1136. padding: 2px;
  1137. margin-top: 2px;
  1138. font-size: xx-small;
  1139. .percent-bar {
  1140. height: 4px;
  1141. }
  1142. .sj {
  1143. // position: absolute;
  1144. border-style: solid;
  1145. border-width: 5px 3px 5px 3px;
  1146. border-color: transparent transparent @green transparent;
  1147. width: 0px;
  1148. height: 0px;
  1149. top: 8px;
  1150. }
  1151. .yj {
  1152. // position: absolute;
  1153. border-style: solid;
  1154. border-width: 5px 3px 5px 3px;
  1155. border-color: transparent transparent @yellow transparent;
  1156. width: 0px;
  1157. height: 0px;
  1158. top: 8px;
  1159. }
  1160. }
  1161. }
  1162. &:first-child {
  1163. margin-left: 0px;
  1164. }
  1165. }
  1166. }
  1167. &:last-child {
  1168. margin-right: 0px;
  1169. }
  1170. }
  1171. }
  1172. .top {
  1173. display: flex;
  1174. margin-bottom: 16px;
  1175. .top-left {
  1176. flex: 1 0 auto;
  1177. .top-left-header {
  1178. display: flex;
  1179. justify-content: space-between;
  1180. margin-bottom: 16px;
  1181. .header-left {
  1182. display: flex;
  1183. .selecttion {
  1184. flex: 1 0 250px;
  1185. width: 250px;
  1186. display: flex;
  1187. .item {
  1188. flex: 0 0 44px;
  1189. height: 28px;
  1190. line-height: 28px;
  1191. text-align: center;
  1192. border: 1px solid @gray;
  1193. margin-right: 8px;
  1194. font-size: 14px;
  1195. color: @gray;
  1196. cursor: pointer;
  1197. &.active,
  1198. &:hover {
  1199. background: fade(@purple, 60);
  1200. color: @white;
  1201. }
  1202. }
  1203. }
  1204. }
  1205. .header-right {
  1206. display: flex;
  1207. margin-right: 12px;
  1208. & > div {
  1209. width: 84px;
  1210. height: 28px;
  1211. line-height: 28px;
  1212. border: 1px solid @gray;
  1213. text-align: center;
  1214. color: @gray;
  1215. font-size: 14px;
  1216. cursor: pointer;
  1217. &:first-child {
  1218. border-top-left-radius: 16px;
  1219. border-bottom-left-radius: 16px;
  1220. }
  1221. &:last-child {
  1222. border-top-right-radius: 16px;
  1223. border-bottom-right-radius: 16px;
  1224. }
  1225. &.active,
  1226. &:hover {
  1227. background: fade(@green, 20);
  1228. border-color: @green;
  1229. color: @green;
  1230. }
  1231. }
  1232. & > span {
  1233. width: 84px;
  1234. height: 28px;
  1235. line-height: 28px;
  1236. border: 1px solid @gray;
  1237. text-align: center;
  1238. color: @gray;
  1239. font-size: 14px;
  1240. cursor: no-drop;
  1241. &:first-child {
  1242. border-top-left-radius: 16px;
  1243. border-bottom-left-radius: 16px;
  1244. }
  1245. &:last-child {
  1246. border-top-right-radius: 16px;
  1247. border-bottom-right-radius: 16px;
  1248. }
  1249. }
  1250. }
  1251. }
  1252. .table {
  1253. .el-table__body table,
  1254. .el-table__header-wrapper table {
  1255. width: 100%;
  1256. }
  1257. &.el-table thead tr:first-child th {
  1258. background: fade(@gray, 40);
  1259. border-bottom: 1px solid #0b1010;
  1260. border-right: 1px solid #0b1010;
  1261. }
  1262. &.el-table thead tr:last-child th {
  1263. background: fade(@gray, 20);
  1264. .cell {
  1265. height: 116px;
  1266. padding: 12px 6px;
  1267. border-right: 1px solid #0b1010;
  1268. }
  1269. }
  1270. &.el-table tr td {
  1271. height: 35px;
  1272. line-height: 35px;
  1273. }
  1274. }
  1275. }
  1276. .top-right {
  1277. flex: 0 0 200px;
  1278. margin-left: 8px;
  1279. .rank-title {
  1280. position: relative;
  1281. height: 28px;
  1282. line-height: 28px;
  1283. border: 1px solid fade(@green, 40);
  1284. text-align: center;
  1285. color: @green;
  1286. font-size: 14px;
  1287. .border {
  1288. position: absolute;
  1289. width: 8px;
  1290. height: 8px;
  1291. border: 2px solid fade(@green, 60);
  1292. &.top-left {
  1293. left: -1px;
  1294. top: -1px;
  1295. border-right: 0px;
  1296. border-bottom: 0px;
  1297. }
  1298. &.top-right {
  1299. top: -1px;
  1300. right: -1px;
  1301. border-left: 0px;
  1302. border-bottom: 0px;
  1303. }
  1304. &.bottom-left {
  1305. bottom: -1px;
  1306. left: -1px;
  1307. border-right: 0px;
  1308. border-top: 0px;
  1309. }
  1310. &.bottom-right {
  1311. bottom: -1px;
  1312. right: -1px;
  1313. border-left: 0px;
  1314. border-top: 0px;
  1315. }
  1316. }
  1317. &::before {
  1318. content: " ";
  1319. position: absolute;
  1320. width: 100%;
  1321. height: 100%;
  1322. left: 0;
  1323. background: linear-gradient(
  1324. 135deg,
  1325. rgba(5, 187, 76, 0.4),
  1326. transparent,
  1327. transparent,
  1328. transparent,
  1329. rgba(5, 187, 76, 0.4)
  1330. );
  1331. }
  1332. }
  1333. .rank-block {
  1334. height: 8px;
  1335. width: 100%;
  1336. border: 1px solid fade(@green, 40);
  1337. border-left: 0px;
  1338. border-right: 0px;
  1339. background: fade(@green, 20);
  1340. margin: 4px 0;
  1341. opacity: 0.5;
  1342. }
  1343. .rank-table {
  1344. border: 1px solid fade(@green, 40);
  1345. &.el-table.el-table--striped
  1346. .el-table__body
  1347. tr.el-table__row--striped
  1348. td {
  1349. background: fade(@green, 10);
  1350. }
  1351. &.el-table.el-table--striped
  1352. .el-table__body
  1353. tr.el-table__row--striped:hover
  1354. td {
  1355. background: fade(@green, 10) !important;
  1356. }
  1357. .rank-index {
  1358. height: 20px;
  1359. width: 20px;
  1360. line-height: 20px;
  1361. text-align: center;
  1362. margin: auto;
  1363. &.index-1 {
  1364. background: fade(@purple, 60);
  1365. color: #fff;
  1366. border: 1px solid @purple;
  1367. }
  1368. &.index-2 {
  1369. background: fade(#2d6e76, 60);
  1370. color: #fff;
  1371. border: 1px solid #2d6e76;
  1372. }
  1373. &.index-3 {
  1374. background: fade(#366626, 60);
  1375. color: #fff;
  1376. border: 1px solid #366626;
  1377. }
  1378. }
  1379. &.el-table thead tr th {
  1380. background: fade(@green, 10);
  1381. border-bottom: 1px solid #0b1010;
  1382. border-right: 1px solid #0b1010;
  1383. height: 116px;
  1384. }
  1385. &.el-table thead tr:first-child th:last-child {
  1386. background: fade(@green, 20);
  1387. border-bottom: 1px solid #0b1010;
  1388. border-right: 1px solid #0b1010;
  1389. height: 30px;
  1390. }
  1391. &.el-table tr td {
  1392. height: 35px;
  1393. line-height: 35px;
  1394. }
  1395. }
  1396. }
  1397. }
  1398. .bottom {
  1399. height: 400px;
  1400. }
  1401. }
  1402. </style>