power-benchmarking.vue 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482
  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, timetype);
  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, timetype) {
  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. if (timetype === "日") {
  960. this.increasescapacity = 30;
  961. } else if (timetype === "月") {
  962. this.increasescapacity = 277;
  963. } else {
  964. this.increasescapacity = 634;
  965. }
  966. // this.increasescapacity = Math.abs(
  967. // this.filter(jizhun.actualpower - shiji.actualpower)
  968. // );
  969. // 理论电量平衡分析
  970. for (let item of this.analyselist) {
  971. let key = item.label;
  972. item.actual = this.filter(shiji[key]);
  973. item.mom = this.filter(shiji[key] - huanbi[key]); //环比
  974. item.yoy = this.filter(shiji[key] - tongbi[key]); //同比
  975. item.expect = this.filter(shiji[key] - jizhun[key]);
  976. }
  977. // 管理效率指标
  978. for (let item of this.managelist) {
  979. let key = item.label;
  980. item.actual = Math.abs(this.filter(shiji[key]));
  981. item.mom = Math.abs(this.filter(shiji[key] - huanbi[key])); //环比
  982. item.yoy = Math.abs(this.filter(shiji[key] - tongbi[key])); //同比
  983. item.expect = Math.abs(this.filter(shiji[key] - jizhun[key]));
  984. }
  985. // 经济指标
  986. for (let item of this.economiclist) {
  987. let key = item.label;
  988. item.actual = this.filter(shiji[key]);
  989. item.mom = this.filter(shiji[key] - huanbi[key]); //环比
  990. item.yoy = this.filter(shiji[key] - tongbi[key]); //同比
  991. item.expect = this.filter(shiji[key] - jizhun[key]);
  992. }
  993. },
  994. // 保留小数位l
  995. filter(num) {
  996. return num % 1 === 0 ? num : num.toFixed(1);
  997. },
  998. resetTableSize(themeName) {
  999. this.$nextTick(() => {
  1000. this.eltableData.column.forEach((pEle, pIndex) => {
  1001. pEle.child.forEach((cEle, cIndex) => {
  1002. const width =
  1003. this.eltableDataBackup.column[pIndex].child[cIndex].width;
  1004. cEle.width = themeName === "dark" ? width : width - 1;
  1005. });
  1006. });
  1007. this.$refs?.jjyxTableRef?.$refs?.groupTable?.doLayout();
  1008. });
  1009. },
  1010. },
  1011. watch: {
  1012. "$store.state.themeName"(themeName) {
  1013. this.resetTableSize(themeName);
  1014. },
  1015. },
  1016. };
  1017. </script>
  1018. <style lang="less">
  1019. .power-benchmarking-page {
  1020. .static {
  1021. display: flex;
  1022. height: 162px;
  1023. margin-bottom: 8px;
  1024. .static-main {
  1025. position: relative;
  1026. flex: 0 0 150px;
  1027. height: 162px;
  1028. border: 1px solid fade(@green, 60);
  1029. padding: 8px;
  1030. background: fade(@gray, 20);
  1031. margin-right: 8px;
  1032. .dot {
  1033. position: absolute;
  1034. width: 3px;
  1035. height: 3px;
  1036. background: @green;
  1037. &.top-left {
  1038. top: 5px;
  1039. left: 5px;
  1040. }
  1041. &.bottom-left {
  1042. bottom: 5px;
  1043. left: 5px;
  1044. }
  1045. &.top-rignt {
  1046. top: 5px;
  1047. right: 5px;
  1048. }
  1049. &.bottom-right {
  1050. bottom: 5px;
  1051. right: 5px;
  1052. }
  1053. }
  1054. .icon {
  1055. height: 40px;
  1056. margin: 8px 0;
  1057. display: flex;
  1058. justify-content: center;
  1059. i {
  1060. width: 36px;
  1061. height: 36px;
  1062. padding: 2px;
  1063. background: @green;
  1064. border-radius: 100%;
  1065. border: 4px solid @gray;
  1066. svg {
  1067. width: 24px;
  1068. height: 24px;
  1069. use {
  1070. fill: #000;
  1071. }
  1072. }
  1073. }
  1074. }
  1075. .info {
  1076. text-align: center;
  1077. .title {
  1078. font-size: 18px;
  1079. margin-bottom: 12px;
  1080. }
  1081. .value {
  1082. font-size: 18px;
  1083. color: @green;
  1084. margin-bottom: 4px;
  1085. }
  1086. .unit {
  1087. padding: 0 8px;
  1088. text-align: right;
  1089. }
  1090. }
  1091. }
  1092. .static-items {
  1093. border: 1px solid fade(@gray, 60);
  1094. margin-right: 8px;
  1095. .static-items-title {
  1096. text-align: center;
  1097. line-height: 27px;
  1098. height: 27px;
  1099. display: flex;
  1100. justify-content: center;
  1101. align-items: center;
  1102. color: @green;
  1103. }
  1104. .items {
  1105. display: flex;
  1106. justify-content: space-between;
  1107. .item {
  1108. // flex: 0 0 138px;
  1109. width: 136px;
  1110. height: 133px;
  1111. margin-left: 8px;
  1112. background: fade(@gray, 20);
  1113. text-align: center;
  1114. padding: 8px;
  1115. & > .title {
  1116. font-size: 14px;
  1117. color: @gray-l;
  1118. }
  1119. & > .value {
  1120. font-family: @font-family-num;
  1121. margin: 8px 0;
  1122. }
  1123. & > .up-down {
  1124. display: flex;
  1125. justify-content: space-around;
  1126. margin: 15px 0;
  1127. font-size: xx-small;
  1128. .up-down-item {
  1129. flex: 1 0 auto;
  1130. display: flex;
  1131. align-items: center;
  1132. justify-content: space-around;
  1133. }
  1134. }
  1135. & > .percent {
  1136. display: flex;
  1137. .percent-box {
  1138. position: relative;
  1139. height: 10px;
  1140. border: 1px solid @gray;
  1141. margin-right: 8px;
  1142. width: calc(100% - 38px);
  1143. padding: 2px;
  1144. margin-top: 2px;
  1145. font-size: xx-small;
  1146. .percent-bar {
  1147. height: 4px;
  1148. }
  1149. .sj {
  1150. // position: absolute;
  1151. border-style: solid;
  1152. border-width: 5px 3px 5px 3px;
  1153. border-color: transparent transparent @green transparent;
  1154. width: 0px;
  1155. height: 0px;
  1156. top: 8px;
  1157. }
  1158. .yj {
  1159. // position: absolute;
  1160. border-style: solid;
  1161. border-width: 5px 3px 5px 3px;
  1162. border-color: transparent transparent @yellow transparent;
  1163. width: 0px;
  1164. height: 0px;
  1165. top: 8px;
  1166. }
  1167. }
  1168. }
  1169. &:first-child {
  1170. margin-left: 0px;
  1171. }
  1172. }
  1173. }
  1174. &:last-child {
  1175. margin-right: 0px;
  1176. }
  1177. }
  1178. }
  1179. .top {
  1180. display: flex;
  1181. margin-bottom: 16px;
  1182. .top-left {
  1183. flex: 1 0 auto;
  1184. .top-left-header {
  1185. display: flex;
  1186. justify-content: space-between;
  1187. margin-bottom: 16px;
  1188. .header-left {
  1189. display: flex;
  1190. .selecttion {
  1191. flex: 1 0 250px;
  1192. width: 250px;
  1193. display: flex;
  1194. .item {
  1195. flex: 0 0 44px;
  1196. height: 28px;
  1197. line-height: 28px;
  1198. text-align: center;
  1199. border: 1px solid @gray;
  1200. margin-right: 8px;
  1201. font-size: 14px;
  1202. color: @gray;
  1203. cursor: pointer;
  1204. &.active,
  1205. &:hover {
  1206. background: fade(@purple, 60);
  1207. color: @white;
  1208. }
  1209. }
  1210. }
  1211. }
  1212. .header-right {
  1213. display: flex;
  1214. margin-right: 12px;
  1215. & > div {
  1216. width: 84px;
  1217. height: 28px;
  1218. line-height: 28px;
  1219. border: 1px solid @gray;
  1220. text-align: center;
  1221. color: @gray;
  1222. font-size: 14px;
  1223. cursor: pointer;
  1224. &:first-child {
  1225. border-top-left-radius: 16px;
  1226. border-bottom-left-radius: 16px;
  1227. }
  1228. &:last-child {
  1229. border-top-right-radius: 16px;
  1230. border-bottom-right-radius: 16px;
  1231. }
  1232. &.active,
  1233. &:hover {
  1234. background: fade(@green, 20);
  1235. border-color: @green;
  1236. color: @green;
  1237. }
  1238. }
  1239. & > span {
  1240. width: 84px;
  1241. height: 28px;
  1242. line-height: 28px;
  1243. border: 1px solid @gray;
  1244. text-align: center;
  1245. color: @gray;
  1246. font-size: 14px;
  1247. cursor: no-drop;
  1248. &:first-child {
  1249. border-top-left-radius: 16px;
  1250. border-bottom-left-radius: 16px;
  1251. }
  1252. &:last-child {
  1253. border-top-right-radius: 16px;
  1254. border-bottom-right-radius: 16px;
  1255. }
  1256. }
  1257. }
  1258. }
  1259. .table {
  1260. .el-table__body table,
  1261. .el-table__header-wrapper table {
  1262. width: 100%;
  1263. }
  1264. &.el-table thead tr:first-child th {
  1265. background: fade(@gray, 40);
  1266. border-bottom: 1px solid #0b1010;
  1267. border-right: 1px solid #0b1010;
  1268. }
  1269. &.el-table thead tr:last-child th {
  1270. background: fade(@gray, 20);
  1271. .cell {
  1272. height: 116px;
  1273. padding: 12px 6px;
  1274. border-right: 1px solid #0b1010;
  1275. }
  1276. }
  1277. &.el-table tr td {
  1278. height: 35px;
  1279. line-height: 35px;
  1280. }
  1281. }
  1282. }
  1283. .top-right {
  1284. flex: 0 0 200px;
  1285. margin-left: 8px;
  1286. .rank-title {
  1287. position: relative;
  1288. height: 28px;
  1289. line-height: 28px;
  1290. border: 1px solid fade(@green, 40);
  1291. text-align: center;
  1292. color: @green;
  1293. font-size: 14px;
  1294. .border {
  1295. position: absolute;
  1296. width: 8px;
  1297. height: 8px;
  1298. border: 2px solid fade(@green, 60);
  1299. &.top-left {
  1300. left: -1px;
  1301. top: -1px;
  1302. border-right: 0px;
  1303. border-bottom: 0px;
  1304. }
  1305. &.top-right {
  1306. top: -1px;
  1307. right: -1px;
  1308. border-left: 0px;
  1309. border-bottom: 0px;
  1310. }
  1311. &.bottom-left {
  1312. bottom: -1px;
  1313. left: -1px;
  1314. border-right: 0px;
  1315. border-top: 0px;
  1316. }
  1317. &.bottom-right {
  1318. bottom: -1px;
  1319. right: -1px;
  1320. border-left: 0px;
  1321. border-top: 0px;
  1322. }
  1323. }
  1324. &::before {
  1325. content: " ";
  1326. position: absolute;
  1327. width: 100%;
  1328. height: 100%;
  1329. left: 0;
  1330. background: linear-gradient(
  1331. 135deg,
  1332. rgba(5, 187, 76, 0.4),
  1333. transparent,
  1334. transparent,
  1335. transparent,
  1336. rgba(5, 187, 76, 0.4)
  1337. );
  1338. }
  1339. }
  1340. .rank-block {
  1341. height: 8px;
  1342. width: 100%;
  1343. border: 1px solid fade(@green, 40);
  1344. border-left: 0px;
  1345. border-right: 0px;
  1346. background: fade(@green, 20);
  1347. margin: 4px 0;
  1348. opacity: 0.5;
  1349. }
  1350. .rank-table {
  1351. border: 1px solid fade(@green, 40);
  1352. &.el-table.el-table--striped
  1353. .el-table__body
  1354. tr.el-table__row--striped
  1355. td {
  1356. background: fade(@green, 10);
  1357. }
  1358. &.el-table.el-table--striped
  1359. .el-table__body
  1360. tr.el-table__row--striped:hover
  1361. td {
  1362. background: fade(@green, 10) !important;
  1363. }
  1364. .rank-index {
  1365. height: 20px;
  1366. width: 20px;
  1367. line-height: 20px;
  1368. text-align: center;
  1369. margin: auto;
  1370. &.index-1 {
  1371. background: fade(@purple, 60);
  1372. color: #fff;
  1373. border: 1px solid @purple;
  1374. }
  1375. &.index-2 {
  1376. background: fade(#2d6e76, 60);
  1377. color: #fff;
  1378. border: 1px solid #2d6e76;
  1379. }
  1380. &.index-3 {
  1381. background: fade(#366626, 60);
  1382. color: #fff;
  1383. border: 1px solid #366626;
  1384. }
  1385. }
  1386. &.el-table thead tr th {
  1387. background: fade(@green, 10);
  1388. border-bottom: 1px solid #0b1010;
  1389. border-right: 1px solid #0b1010;
  1390. height: 116px;
  1391. }
  1392. &.el-table thead tr:first-child th:last-child {
  1393. background: fade(@green, 20);
  1394. border-bottom: 1px solid #0b1010;
  1395. border-right: 1px solid #0b1010;
  1396. height: 30px;
  1397. }
  1398. &.el-table tr td {
  1399. height: 35px;
  1400. line-height: 35px;
  1401. }
  1402. }
  1403. }
  1404. }
  1405. .bottom {
  1406. height: 400px;
  1407. }
  1408. }
  1409. </style>