index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. <template>
  2. <div class="home-body" style="height: 93vh">
  3. <HomeNav
  4. :hiddenProject="true"
  5. :hiddenLine="true"
  6. :hiddenSearch="true"
  7. @firstRender="firstRender"
  8. />
  9. <div class="title">
  10. <el-select v-model="tabIndex" placeholder="请选择">
  11. <el-option
  12. v-show="item.id"
  13. v-for="(item, index) in tabOptions"
  14. :key="index"
  15. :label="item.name"
  16. :value="item.id"
  17. >
  18. </el-option>
  19. </el-select>
  20. <el-select
  21. size="mini"
  22. v-model="company"
  23. placeholder="请选择"
  24. @change="handleCompanyChange(company)"
  25. >
  26. <el-option
  27. v-for="item in companyOptions"
  28. :key="item.id"
  29. :label="item.aname"
  30. :value="item.id"
  31. >
  32. </el-option>
  33. </el-select>
  34. <!-- <div class="tabCut">
  35. <div
  36. @click="tabClick(val.id)"
  37. :class="tabIndex === val.id ? 'active' : ''"
  38. v-for="val in tabOptions"
  39. :key="val.id"
  40. >
  41. <span>{{ val.name }}</span>
  42. </div>
  43. </div> -->
  44. <div class="station">
  45. 场站:
  46. <el-select
  47. size="mini"
  48. v-model="stationObj"
  49. placeholder="请选择"
  50. @change="handleStationChange(stationObj)"
  51. clearable
  52. >
  53. <el-option
  54. v-for="item in stationList"
  55. :key="item.id"
  56. :label="item.aname"
  57. :value="item.id"
  58. >
  59. </el-option>
  60. </el-select>
  61. </div>
  62. <template v-if="tabIndex === -1">
  63. <div class="station">
  64. 项目:
  65. <el-select
  66. size="mini"
  67. v-model="projectObj"
  68. placeholder="请选择"
  69. @change="handleProjectChange(projectObj)"
  70. clearable
  71. >
  72. <el-option
  73. v-for="item in projectList"
  74. :key="item.id"
  75. :label="item.aname"
  76. :value="item.id"
  77. >
  78. </el-option>
  79. </el-select>
  80. </div>
  81. <div class="station">
  82. 线路:
  83. <el-select
  84. size="mini"
  85. v-model="lineObj"
  86. placeholder="请选择"
  87. clearable
  88. @change="typeClick('1')"
  89. >
  90. <el-option
  91. v-for="item in lineList"
  92. :key="item.id"
  93. :label="item.aname"
  94. :value="item.id"
  95. >
  96. </el-option>
  97. </el-select>
  98. </div>
  99. </template>
  100. <div class="dates">
  101. 开始日期
  102. <div class="search-input">
  103. <el-date-picker
  104. v-model="starTime"
  105. type="date"
  106. value-format="YYYY-MM-DD"
  107. placeholder="选择日期"
  108. popper-class="date-select"
  109. @change="typeClick('1')"
  110. >
  111. </el-date-picker>
  112. </div>
  113. </div>
  114. <div class="dates">
  115. 结束日期
  116. <div class="search-input">
  117. <el-date-picker
  118. v-model="endTime"
  119. type="date"
  120. value-format="YYYY-MM-DD"
  121. placeholder="选择日期"
  122. popper-class="date-select"
  123. @change="typeClick('1')"
  124. >
  125. </el-date-picker>
  126. </div>
  127. </div>
  128. <div class="but">
  129. <el-button
  130. round
  131. size="mini"
  132. class="buttons active"
  133. @click="getPerformance"
  134. >搜索</el-button
  135. >
  136. <el-button round size="mini" class="buttons" @click="mxClick"
  137. >明细</el-button
  138. >
  139. </div>
  140. </div>
  141. <div class="tabCut1" v-if="tabIndex === -1">
  142. <div
  143. class="tabCut-item"
  144. @click="typeClick(val.id)"
  145. :class="typeIndex === val.id ? 'active' : ''"
  146. v-for="val in typeOptions"
  147. :key="val.id"
  148. >
  149. <span>{{ val.name }}</span>
  150. </div>
  151. </div>
  152. <div class="performance" style="height: 90vh">
  153. <div class="economicTable" style="height: 86vh">
  154. <el-table
  155. :data="tableData"
  156. size="mini"
  157. :cell-style="{ padding: '6px' }"
  158. :row-style="{ height: '0px' }"
  159. stripe
  160. @header-click="onHeaderClick"
  161. >
  162. <el-table-column align="center" prop="" label="" width="900">
  163. </el-table-column>
  164. <el-table-column
  165. align="center"
  166. prop="name"
  167. show-overflow-tooltip
  168. label="名称"
  169. >
  170. </el-table-column>
  171. <el-table-column align="center" prop="llfdl" label="理论发电量">
  172. </el-table-column>
  173. <el-table-column align="center" prop="sjfdl" label="实际发电量">
  174. </el-table-column>
  175. <el-table-column
  176. align="center"
  177. prop="fnlly"
  178. :label="tabIndex === -1 ? '风能利用率%' : '光能利用率%'"
  179. width="120"
  180. >
  181. </el-table-column>
  182. <el-table-column
  183. align="center"
  184. prop="speed"
  185. :label="tabIndex === -1 ? '风速' : '光照'"
  186. >
  187. </el-table-column>
  188. <el-table-column align="center" prop="fjhjx" label="故障">
  189. </el-table-column>
  190. <el-table-column align="center" prop="jhjx" label="检修">
  191. </el-table-column>
  192. <el-table-column align="center" prop="sl" label="受累">
  193. </el-table-column>
  194. <el-table-column align="center" prop="xd" label="限电">
  195. </el-table-column>
  196. <el-table-column align="center" prop="xn" label="性能">
  197. </el-table-column>
  198. </el-table>
  199. </div>
  200. <div class="left">
  201. <bar-line-chart
  202. v-if="showDisplay"
  203. :height="height"
  204. :bardata="bardata"
  205. :lineData="lineData"
  206. :color="barColor"
  207. lineName="理论发电量"
  208. />
  209. <div class="lyl" :style="{ height: tableData.length * 38 + 'px' }">
  210. <div class="lyl-item" v-for="(item, index) in tableData" :key="index">
  211. {{ item.fnlly }}%
  212. <img class="lyl-item-img" src="@assets/img/images/fnlyl.png" />
  213. </div>
  214. </div>
  215. <div class="dashed" :style="{ height: height }"></div>
  216. </div>
  217. </div>
  218. </div>
  219. </template>
  220. <script>
  221. import BarLineChart from "../compontent/bar-line-chart.vue";
  222. import { companys } from "@/api/curveAnalyse";
  223. import dayjs from "dayjs";
  224. import {
  225. getStation,
  226. getProject,
  227. getLine,
  228. performance,
  229. } from "@/api/performance";
  230. export default {
  231. name: "performanceRankingList", //风机绩效榜
  232. components: {
  233. BarLineChart,
  234. },
  235. data() {
  236. return {
  237. barColor: [
  238. "#1c99ff",
  239. "#e17e23",
  240. "#ba3237",
  241. "#c531c7",
  242. "#ffffff",
  243. "#05bb4c",
  244. ],
  245. company: "",
  246. companyOptions: [],
  247. stationObj: "",
  248. stationList: [],
  249. projectObj: "",
  250. projectList: [],
  251. lineObj: "",
  252. lineList: [],
  253. starTime: "",
  254. endTime: "",
  255. tabIndex: -1,
  256. bardata: [],
  257. lineData: [],
  258. tabType: -1,
  259. tabOptions: [
  260. { id: -1, name: "风电" },
  261. { id: -2, name: "光伏" },
  262. ],
  263. typeIndex: "1",
  264. typeOptions: [
  265. { id: "1", name: "风场" },
  266. { id: "2", name: "项目" },
  267. { id: "3", name: "线路" },
  268. ],
  269. tableData: [],
  270. showDisplay: true,
  271. height: "880px",
  272. sort: "",
  273. target: "",
  274. sortList: [
  275. {
  276. id: "name",
  277. sort: false,
  278. },
  279. {
  280. id: "llfdl",
  281. sort: false,
  282. },
  283. {
  284. id: "sjfdl",
  285. sort: false,
  286. },
  287. {
  288. id: "speed",
  289. sort: false,
  290. },
  291. {
  292. id: "fjhjx",
  293. sort: false,
  294. },
  295. {
  296. id: "jhjx",
  297. sort: false,
  298. },
  299. {
  300. id: "sl",
  301. sort: false,
  302. },
  303. {
  304. id: "xd",
  305. sort: false,
  306. },
  307. {
  308. id: "xn",
  309. sort: false,
  310. },
  311. {
  312. id: "fnlly",
  313. sort: false,
  314. },
  315. ],
  316. };
  317. },
  318. computed: {},
  319. created() {
  320. let date = new Date();
  321. date.setDate(1);
  322. let month = parseInt(date.getMonth() + 1);
  323. let day = date.getDate();
  324. if (month < 10) {
  325. month = "0" + month;
  326. }
  327. if (day < 10) {
  328. day = "0" + day;
  329. }
  330. this.starTime = date.getFullYear() + "-" + month + "-" + day;
  331. this.endTime = dayjs(new Date().getTime()).format("YYYY-MM-DD");
  332. this.initialization();
  333. },
  334. methods: {
  335. onHeaderClick(column) {
  336. console.log(column);
  337. this.target = column.property;
  338. this.sortList.forEach((item) => {
  339. if (item.id === column.property) {
  340. item.sort = !item.sort;
  341. this.sort = item.sort ? 1 : 2;
  342. } else {
  343. item.sort = false;
  344. }
  345. });
  346. this.getPerformance();
  347. },
  348. initialization() {
  349. companys().then((res) => {
  350. this.companyOptions = res.data;
  351. if (res.data.length) {
  352. this.company = res.data[0].id;
  353. this.getStation(res.data[0].id);
  354. } else {
  355. (this.company = ""),
  356. (this.stationObj = ""),
  357. (this.stationList = []),
  358. (this.projectObj = ""),
  359. (this.projectList = []),
  360. (this.lineObj = ""),
  361. (this.lineList = []);
  362. }
  363. });
  364. },
  365. getStation(companyids) {
  366. getStation({
  367. companyids: companyids,
  368. type: this.tabIndex,
  369. }).then((res) => {
  370. if (res.data.length) {
  371. this.stationList = res.data;
  372. this.getProject(res.data[0].id);
  373. } else {
  374. (this.stationObj = ""),
  375. (this.stationList = []),
  376. (this.projectObj = ""),
  377. (this.projectList = []),
  378. (this.lineObj = ""),
  379. (this.lineList = []);
  380. }
  381. });
  382. },
  383. getProject(wpids) {
  384. getProject({
  385. wpids: wpids,
  386. }).then((res) => {
  387. if (res.data.length) {
  388. this.projectList = res.data;
  389. this.getLine(res.data[0].id);
  390. } else {
  391. (this.projectObj = ""),
  392. (this.projectList = []),
  393. (this.lineObj = ""),
  394. (this.lineList = []);
  395. }
  396. });
  397. },
  398. getLine(pjids) {
  399. getLine({
  400. pjids: pjids,
  401. }).then((res) => {
  402. if (res.data.length) {
  403. this.lineList = res.data;
  404. } else {
  405. (this.lineObj = ""), (this.lineList = []);
  406. }
  407. this.getPerformance();
  408. });
  409. },
  410. handleCompanyChange(val) {
  411. this.typeIndex = "1";
  412. this.getStation(val);
  413. },
  414. handleStationChange(val) {
  415. this.typeIndex = "1";
  416. this.getProject(val);
  417. },
  418. handleProjectChange(val) {
  419. this.typeIndex = "1";
  420. this.getLine(val);
  421. },
  422. tabClick(data) {
  423. this.tabIndex = data;
  424. (this.stationObj = ""),
  425. (this.stationList = []),
  426. (this.projectObj = ""),
  427. (this.projectList = []),
  428. (this.lineObj = ""),
  429. (this.lineList = []);
  430. this.getStation(this.company);
  431. this.getPerformance();
  432. },
  433. typeClick(data) {
  434. this.typeIndex = data;
  435. this.getPerformance();
  436. },
  437. getPerformance() {
  438. performance({
  439. companyid: this.company,
  440. getype: this.tabIndex,
  441. sttype: this.stationObj ? "" : this.typeIndex,
  442. beginDate: this.starTime,
  443. endDate: this.endTime,
  444. wpids: this.stationObj,
  445. projectids: this.projectObj,
  446. lineids: this.lineObj,
  447. target: this.target,
  448. sort: this.sort,
  449. }).then((res) => {
  450. if (res.data) {
  451. let name = [],
  452. data = [],
  453. llfdl = [],
  454. legend = [
  455. "实际电量",
  456. "检修损失电量",
  457. "故障损失电量",
  458. "限电损失电量",
  459. "受累损失电量",
  460. "性能损失电量",
  461. ]; //项目列表
  462. res.data.forEach((item, index) => {
  463. name.push(item.name);
  464. data.push([
  465. item.sjfdl,
  466. item.jhjx,
  467. item.fjhjx,
  468. item.xd,
  469. item.sl,
  470. item.xn,
  471. ]);
  472. llfdl.push(item.llfdl);
  473. });
  474. name.pop();
  475. data.pop();
  476. llfdl.pop();
  477. if (data.length > 0) {
  478. let arr1 = [];
  479. const length = data[0].length;
  480. for (let i = 0; i < length; i++) {
  481. let arr2 = [];
  482. data.forEach((ele) => {
  483. arr2.push(ele[i]);
  484. });
  485. arr1.push(arr2);
  486. }
  487. this.lineData = llfdl;
  488. this.bardata = {
  489. area: name,
  490. legend: legend,
  491. data: arr1,
  492. };
  493. } else {
  494. (this.bardata = []), (this.lineData = []);
  495. }
  496. if (this.lineData.length > 22) {
  497. this.height = this.lineData.length * 37 + 53 + "px";
  498. } else {
  499. this.height = 23 * 37 + 80 + "px";
  500. }
  501. this.showDisplay = false;
  502. setTimeout(() => {
  503. this.showDisplay = true;
  504. }, 10);
  505. this.tableData = res.data;
  506. console.log(111, this.tableData);
  507. }
  508. });
  509. },
  510. mxClick() {
  511. this.$router.push("/benchmarkingManagement/decision1Mx");
  512. },
  513. },
  514. };
  515. </script>
  516. <style lang="less" scoped>
  517. .home-body {
  518. display: flex;
  519. flex-direction: column;
  520. }
  521. .title {
  522. display: flex;
  523. flex-direction: row;
  524. align-items: center;
  525. margin-top: 10px;
  526. padding-left: 20px;
  527. .tabCut {
  528. display: inline-block;
  529. margin: 0 10px;
  530. div {
  531. display: inline-block;
  532. width: 60px;
  533. height: 27px;
  534. border: 1px solid #354460;
  535. text-align: center;
  536. line-height: 25px;
  537. cursor: pointer;
  538. }
  539. div:nth-child(1) {
  540. border-radius: 13px 0px 0px 13px;
  541. }
  542. div:nth-child(2) {
  543. border-radius: 0px 13px 13px 0px;
  544. }
  545. .active {
  546. background-color: #0c3378;
  547. color: #fff;
  548. }
  549. }
  550. .station {
  551. display: flex;
  552. flex-direction: row;
  553. align-items: center;
  554. font-size: 14px;
  555. font-family: Microsoft YaHei;
  556. font-weight: 400;
  557. color: #b3b3b3;
  558. margin-right: 10px;
  559. }
  560. .dates {
  561. display: flex;
  562. flex-direction: row;
  563. align-items: center;
  564. font-size: 14px;
  565. font-family: Microsoft YaHei;
  566. font-weight: 400;
  567. color: #b3b3b3;
  568. margin-right: 10px;
  569. }
  570. .search-input {
  571. margin-left: 10px;
  572. }
  573. .but {
  574. display: flex;
  575. flex-direction: row;
  576. align-content: center;
  577. margin-left: 20px;
  578. }
  579. .buttons {
  580. background-color: rgba(0, 70, 199, 0.2);
  581. border: 1px solid #3b4c6c;
  582. color: #b3b3b3;
  583. font-size: 14px;
  584. &:hover,
  585. &.active {
  586. background-color: rgba(0, 70, 199, 0.5);
  587. color: #ffffff;
  588. }
  589. }
  590. }
  591. .performance {
  592. display: flex;
  593. flex-direction: row;
  594. width: 98.5%;
  595. background-color: rgba(0, 0, 0, 0.4);
  596. margin-top: 10px;
  597. margin-left: 1%;
  598. border-radius: 5px;
  599. overflow-y: auto;
  600. position: relative;
  601. .left {
  602. width: 45%;
  603. height: 100%;
  604. position: absolute;
  605. left: 0;
  606. top: 0;
  607. display: flex;
  608. flex-direction: row;
  609. .dashed {
  610. position: absolute;
  611. width: 1px;
  612. background-image: linear-gradient(
  613. #3a4043 0%,
  614. #3a4043 40%,
  615. transparent 50%
  616. );
  617. background-size: 1px 9px;
  618. margin-top: 45px;
  619. height: 100%;
  620. right: -50px;
  621. }
  622. }
  623. .center {
  624. width: 3%;
  625. height: 90%;
  626. position: relative;
  627. margin-top: 50px;
  628. .using {
  629. width: 100%;
  630. height: 100%;
  631. z-index: 99;
  632. position: absolute;
  633. right: 0px;
  634. top: 0px;
  635. }
  636. }
  637. .dashed1 {
  638. width: 1px;
  639. background-image: linear-gradient(#3a4043 0%, #3a4043 40%, transparent 50%);
  640. background-size: 1px 9px;
  641. margin-top: 45px;
  642. margin-left: 20px;
  643. }
  644. .economicTable {
  645. width: 100%;
  646. }
  647. }
  648. .tabCut1 {
  649. display: flex;
  650. flex-direction: row;
  651. align-items: center;
  652. margin: 10px 0px 0px 20px;
  653. .tabCut-item {
  654. width: 93px;
  655. height: 23px;
  656. display: flex;
  657. align-items: center;
  658. justify-content: center;
  659. margin-right: 10px;
  660. background: rgba(0, 70, 199, 0.4);
  661. color: #abb5cc;
  662. position: relative;
  663. }
  664. .active {
  665. background: rgba(0, 70, 199, 0.7);
  666. color: #fff;
  667. }
  668. .active:before {
  669. content: "";
  670. width: 1px;
  671. height: 7px;
  672. background-color: #ffffff;
  673. position: absolute;
  674. left: 0;
  675. }
  676. .active:after {
  677. content: "";
  678. width: 1px;
  679. height: 7px;
  680. background-color: #ffffff;
  681. position: absolute;
  682. right: 0;
  683. }
  684. }
  685. .lyl {
  686. display: flex;
  687. flex-direction: column;
  688. align-items: center;
  689. width: 70px;
  690. font-size: 14px;
  691. font-family: Arial;
  692. font-weight: 400;
  693. color: #1c98fe;
  694. margin-top: 37px;
  695. margin-left: 10px;
  696. }
  697. .lyl-item {
  698. display: flex;
  699. align-items: center;
  700. justify-content: center;
  701. height: 37px;
  702. position: relative;
  703. width: 120px;
  704. }
  705. .lyl-item-img {
  706. position: absolute;
  707. left: 0;
  708. bottom: 0;
  709. height: 32px;
  710. }
  711. </style>