index.vue 18 KB

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