index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. <template>
  2. <div class="parcel-box">
  3. <div class="search">
  4. <div class="search-left">
  5. <el-select
  6. size="mini"
  7. v-model="company"
  8. placeholder="请选择"
  9. @change="search()"
  10. >
  11. <el-option
  12. v-for="item in companyOptions"
  13. :key="item.id"
  14. :label="item.aname"
  15. :value="item.id"
  16. >
  17. </el-option>
  18. </el-select>
  19. <div class="tabCut">
  20. <div
  21. @click="tabClick(val.id)"
  22. :class="tabIndex === val.id ? 'active' : ''"
  23. v-for="val in tabOptions"
  24. :key="val.id"
  25. >
  26. <span>{{ val.name }}</span>
  27. </div>
  28. </div>
  29. <div class="search-input">
  30. <el-date-picker
  31. size="mini"
  32. v-model="searchYear"
  33. type="year"
  34. value-format="YYYY"
  35. placeholder="选择年"
  36. popper-class="date-select"
  37. >
  38. </el-date-picker>
  39. </div>
  40. <el-button round size="mini" class="searchColor" @click="search"
  41. >搜索</el-button
  42. >
  43. </div>
  44. <div class="search-right">
  45. <img class="select-back" src="@assets/imgs/select-back.png" />
  46. <div class="title-select">
  47. <el-select
  48. v-model="selectValue"
  49. placeholder="请选择"
  50. @change="search()"
  51. clearable
  52. >
  53. <el-option
  54. v-for="item in selectList"
  55. :key="item.name"
  56. :label="item.name"
  57. :value="item.name"
  58. >
  59. </el-option>
  60. </el-select>
  61. </div>
  62. </div>
  63. <!-- <el-button round size="mini">导出</el-button> -->
  64. </div>
  65. <div class="data-bodys">
  66. <div class="line clearfix">
  67. <div class="leftContent line-left">
  68. <span>{{ selectValue }}</span>
  69. </div>
  70. </div>
  71. <div class="economicTable">
  72. <el-table
  73. :data="tableData"
  74. style="width: 100%"
  75. size="mini"
  76. stripe
  77. height="100%"
  78. @row-click="rowClick"
  79. >
  80. <el-table-column
  81. align="center"
  82. prop=""
  83. label="场站"
  84. show-overflow-tooltip
  85. sortable
  86. >
  87. <template v-slot="scope">
  88. <span style="cursor: pointer">{{ scope.row.wpname }}</span>
  89. </template>
  90. </el-table-column>
  91. <el-table-column
  92. align="center"
  93. :label="val"
  94. v-for="(val, index) in tableHead"
  95. :key="index"
  96. width="140"
  97. sortable
  98. >
  99. <template v-slot="scope">
  100. <div v-if="scope.row.wpname == ''">
  101. <el-row>
  102. <el-col :span="12"
  103. ><span>{{ scope.row.data?.current }}</span></el-col
  104. >
  105. <el-col :span="12"
  106. ><span>{{ scope.row.data.sameperiod }}</span></el-col
  107. >
  108. </el-row>
  109. </div>
  110. <div v-else>
  111. <el-row>
  112. <el-col :span="12" class="columnFlex">
  113. <div
  114. v-if="
  115. scope.row.targetList[index]?.current ||
  116. scope.row.targetList[index]?.current === 0
  117. "
  118. class="box-item"
  119. >
  120. <el-tooltip
  121. effect="dark"
  122. :content="scope.row.targetList[index]?.current"
  123. placement="top-start"
  124. >
  125. <div>
  126. <span style="width: 80%">{{
  127. scope.row.targetList &&
  128. scope.row.targetList[index]?.current
  129. }}</span>
  130. </div>
  131. </el-tooltip>
  132. </div>
  133. <div v-else class="box-item">--</div>
  134. <div style="flex: 0 0 auto; line-height: 1">
  135. <Bottom
  136. class="botSvg"
  137. v-if="
  138. scope.row.targetList &&
  139. scope.row.targetList[index]?.current <
  140. scope.row.targetList[index]?.sameperiod
  141. "
  142. />
  143. <Top
  144. class="topSvg"
  145. v-if="
  146. scope.row.targetList &&
  147. scope.row.targetList[index]?.current >
  148. scope.row.targetList[index]?.sameperiod
  149. "
  150. />
  151. </div>
  152. </el-col>
  153. <el-col :span="12"
  154. ><span>{{
  155. scope.row.targetList &&
  156. (scope.row.targetList[index]?.sameperiod ||
  157. scope.row.targetList[index]?.sameperiod === 0
  158. ? scope.row.targetList[index]?.sameperiod
  159. : "--")
  160. }}</span></el-col
  161. >
  162. </el-row>
  163. </div>
  164. </template>
  165. </el-table-column>
  166. </el-table>
  167. </div>
  168. </div>
  169. <div class="echarts">
  170. <div class="chart-name">
  171. <div class="point point-left bottom"></div>
  172. <div class="point point-right bottom"></div>
  173. {{ selectValue }}
  174. </div>
  175. <div style="height: calc(100% - 39px); margin-top: 10px">
  176. <BarCharts
  177. :list="barList"
  178. width="97%"
  179. height="100%"
  180. :top="60"
  181. :pillarName="pillarName"
  182. :xdate="false"
  183. :showLegend="true"
  184. :units="['', '']"
  185. ></BarCharts>
  186. </div>
  187. </div>
  188. </div>
  189. </template>
  190. <script>
  191. // import Panel from "@/components/curveAnalyse/panel.vue";
  192. // import ChartColumnar from '@/components/curveAnalyse/multiple-bar-chart.vue'
  193. import BarCharts from "../../homePage/components/barCharts.vue";
  194. import { companys, mtbfList, mttrList } from "@/api/curveAnalyse";
  195. export default {
  196. name: "curveAnalyse",
  197. components: {
  198. // ChartColumnar,
  199. // Panel,
  200. BarCharts,
  201. },
  202. data() {
  203. return {
  204. pillarName: "",
  205. // echartsData: [],
  206. // tableName: "",
  207. list: [],
  208. // DayPower: {
  209. // // 图表所用单位
  210. // units: [""],
  211. // value: [
  212. // {
  213. // title: "",
  214. // yAxisIndex: 0, // 使用单位
  215. // value: [],
  216. // },
  217. // ],
  218. // },
  219. // BarChartsList: [],
  220. tabIndex: -1,
  221. tabOptions: [
  222. { id: -1, name: "风电" },
  223. { id: -2, name: "光伏" },
  224. ],
  225. // barHeight: '260px',
  226. barList: [],
  227. tableData: [],
  228. tableHead: [
  229. "一月",
  230. "二月",
  231. "三月",
  232. "四月",
  233. "五月",
  234. "六月",
  235. "七月",
  236. "八月",
  237. "九月",
  238. "十月",
  239. "十一月",
  240. "十二月",
  241. ],
  242. company: "",
  243. companyOptions: [],
  244. searchYear: this.getmonthValue(),
  245. selectList: [
  246. {
  247. name: "MTBF",
  248. },
  249. {
  250. name: "MTTR",
  251. },
  252. ],
  253. selectValue: "MTBF",
  254. };
  255. },
  256. watch: {},
  257. filters: {},
  258. computed: {},
  259. created() {
  260. this.initialization();
  261. },
  262. methods: {
  263. compare(property) {
  264. return (a, b) => {
  265. let val1 = a[property];
  266. let val2 = b[property];
  267. return val1 - val2;
  268. };
  269. },
  270. rowClick(list) {
  271. if (list?.wpname) {
  272. let barList = [
  273. {
  274. name: "本期",
  275. children: [],
  276. date: [],
  277. },
  278. {
  279. name: "同期",
  280. children: [],
  281. },
  282. ];
  283. this.pillarName = list.wpname;
  284. list.targetList.forEach((item) => {
  285. barList[0].date.push(item.month + "月");
  286. barList[0].children.push(item.current || 0);
  287. barList[1].children.push(item.compare || 0);
  288. });
  289. this.barList = barList;
  290. }
  291. },
  292. // isNumber(val) {
  293. // return typeof val === "number" && !isNaN(val);
  294. // },
  295. search() {
  296. switch (this.selectValue) {
  297. case "MTBF":
  298. mtbfList({
  299. companys: this.company,
  300. type: this.tabIndex,
  301. year: this.monthChange(this.searchYear),
  302. }).then(({ data: res }) => {
  303. if (res.data) {
  304. let arr = [
  305. {
  306. wpname: "",
  307. data: {
  308. wpname: "期次",
  309. current: "本期",
  310. sameperiod: "同期",
  311. },
  312. },
  313. ];
  314. this.tableData = [...arr, ...res.data];
  315. this.rowClick(res.data[res.data.length - 1]);
  316. }
  317. });
  318. break;
  319. case "MTTR":
  320. mttrList({
  321. companys: this.company,
  322. type: this.tabIndex,
  323. year: this.monthChange(this.searchYear),
  324. }).then(({ data: res }) => {
  325. if (res.data) {
  326. let arr = [
  327. {
  328. wpname: "",
  329. data: {
  330. wpname: "期次",
  331. current: "本期",
  332. sameperiod: "同期",
  333. },
  334. },
  335. ];
  336. this.tableData = [...arr, ...res.data];
  337. this.rowClick(res.data[res.data.length - 1]);
  338. }
  339. });
  340. break;
  341. }
  342. },
  343. monthChange(data) {
  344. let year = new Date(data).getFullYear().toString();
  345. return year;
  346. },
  347. getmonthValue() {
  348. let year = new Date().getFullYear().toString();
  349. return year;
  350. },
  351. tabClick(data) {
  352. this.tabIndex = data;
  353. this.search();
  354. },
  355. initialization() {
  356. companys().then(({ data: res }) => {
  357. if (res.data) {
  358. this.companyOptions = res.data;
  359. this.company = res.data[0].id;
  360. this.search();
  361. }
  362. });
  363. },
  364. },
  365. mounted() {},
  366. beforeUnmount() {},
  367. };
  368. </script>
  369. <style lang="less" scoped>
  370. .parcel-box {
  371. padding: 0 20px;
  372. box-sizing: border-box;
  373. height: 100%;
  374. .search {
  375. display: flex;
  376. flex-direction: row;
  377. padding-top: 10px;
  378. padding-bottom: 10px;
  379. align-items: center;
  380. justify-content: space-between;
  381. .search-left {
  382. display: flex;
  383. flex-direction: row;
  384. align-items: center;
  385. }
  386. .search-right {
  387. position: relative;
  388. .select-back {
  389. position: absolute;
  390. right: 5px;
  391. top: 0px;
  392. z-index: 0;
  393. }
  394. .title-select {
  395. z-index: 2;
  396. }
  397. }
  398. .tabCut {
  399. display: inline-block;
  400. margin: 0 20px;
  401. div {
  402. display: inline-block;
  403. width: 60px;
  404. height: 27px;
  405. border: 1px solid #274934;
  406. text-align: center;
  407. line-height: 25px;
  408. cursor: pointer;
  409. }
  410. div:nth-child(1) {
  411. border-radius: 13px 0px 0px 13px;
  412. border-right-width: 0;
  413. }
  414. div:nth-child(2) {
  415. border-radius: 0px 13px 13px 0px;
  416. }
  417. .active {
  418. background-color: rgba(5, 187, 76, 0.9);
  419. color: #fff;
  420. }
  421. }
  422. button {
  423. margin-left: 10px;
  424. background: rgba(67, 81, 107, 0.3);
  425. border: 1px solid #274934;
  426. color: #b3b3b3;
  427. }
  428. .searchColor {
  429. background-color: rgba(5, 187, 76, 0.2);
  430. border: 1px solid #3b6c53;
  431. color: #b3b3b3;
  432. font-size: 14px;
  433. &:hover {
  434. background-color: rgba(5, 187, 76, 0.5);
  435. color: #ffffff;
  436. }
  437. }
  438. }
  439. .data-bodys {
  440. height: calc(100% - 58px - 350px - 20px);
  441. display: flex;
  442. flex-direction: column;
  443. background-color: rgba(0, 0, 0, 0.45);
  444. border-radius: 5px;
  445. }
  446. .economicTable {
  447. height: calc(100% - 32px);
  448. .el-table__body-wrapper {
  449. .columnFlex {
  450. display: flex;
  451. align-items: center;
  452. }
  453. .box-item {
  454. flex: 1;
  455. white-space: nowrap;
  456. overflow: hidden;
  457. text-overflow: ellipsis;
  458. }
  459. }
  460. .topSvg {
  461. width: 1em;
  462. height: 1em;
  463. color: #1c99ff;
  464. }
  465. .botSvg {
  466. width: 1em;
  467. height: 1em;
  468. color: #ff8300;
  469. }
  470. }
  471. .line {
  472. .leftContent {
  473. width: 242px;
  474. height: 41px;
  475. line-height: 41px;
  476. background: url("~@/assets/imgs/title_left_bg1.png") no-repeat;
  477. padding-left: 25px;
  478. span {
  479. font-size: 16px;
  480. font-family: Microsoft YaHei;
  481. font-weight: 400;
  482. color: #ffffff;
  483. }
  484. }
  485. .rightContent {
  486. width: 212px;
  487. height: 28px;
  488. margin-top: 13px;
  489. background: url("../../../../assets/imgs/title_right_bg.png");
  490. }
  491. .floatRight {
  492. float: right;
  493. }
  494. }
  495. .echarts {
  496. padding-top: 20px;
  497. padding-bottom: 15px;
  498. background-color: rgba(0, 0, 0, 0.45);
  499. border-radius: 5px;
  500. width: 100%;
  501. height: 350px;
  502. }
  503. }
  504. .clearfix::after {
  505. content: "";
  506. clear: both;
  507. height: 0;
  508. line-height: 0;
  509. visibility: hidden;
  510. display: block;
  511. }
  512. .clearfix {
  513. zoom: 1;
  514. }
  515. .line-left {
  516. float: left;
  517. }
  518. .line-right {
  519. float: right;
  520. }
  521. .el-table::before {
  522. height: 0;
  523. }
  524. .compare-lift-down {
  525. margin-left: 7px;
  526. font-size: 14px;
  527. font-family: Arial;
  528. font-weight: 400;
  529. color: #ff8300;
  530. }
  531. .compare-lift-up {
  532. margin-left: 7px;
  533. font-size: 14px;
  534. font-family: Arial;
  535. font-weight: 400;
  536. color: #1c99ff;
  537. }
  538. .chart-name {
  539. display: flex;
  540. align-items: center;
  541. justify-content: center;
  542. position: relative;
  543. width: 100%;
  544. height: 40px;
  545. border-bottom: 1px solid rgba(106, 106, 106, 0.5);
  546. font-size: 16px;
  547. font-family: Microsoft YaHei;
  548. font-weight: 400;
  549. color: #ffffff;
  550. }
  551. .point {
  552. width: 6px;
  553. height: 1px;
  554. background-color: #ffffff;
  555. position: absolute;
  556. &.point-left {
  557. left: 0;
  558. }
  559. &.point-right {
  560. right: 0;
  561. }
  562. &.top {
  563. top: -1px;
  564. }
  565. &.bottom {
  566. bottom: -1px;
  567. }
  568. }
  569. </style>