ProjectProgress.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. <template>
  2. <transition
  3. appear
  4. name="animate__animated animate__move"
  5. enter-active-class="animate__slideInRight"
  6. leave-active-class="animate__slideOutRight"
  7. >
  8. <div class="widget-ProjectProgress">
  9. <div class="head">
  10. <div class="title">
  11. <div class="icon"></div>
  12. <span class="site-info">项目进展</span>
  13. </div>
  14. </div>
  15. <div class="content-info">
  16. <div class="content-item investment">
  17. <div class="title">
  18. <div class="icon"></div>
  19. <span class="item-name">投资完成情况</span>
  20. </div>
  21. <div class="content">
  22. <ComOneBatteryChart v-on="{ fontSize }" :chartData="investData" />
  23. </div>
  24. </div>
  25. <div class="content-item">
  26. <div class="title">
  27. <div class="icon"></div>
  28. <span class="item-name">设计进度</span>
  29. </div>
  30. <div class="content">
  31. <ComProgressChart v-on="{ fontSize }" :chartData="progressData" />
  32. </div>
  33. </div>
  34. <div class="content-item">
  35. <div class="title">
  36. <div class="icon"></div>
  37. <span class="item-name">施工进度</span>
  38. </div>
  39. <div class="content build-progress">
  40. <div class="build-progress-item">
  41. <div class="build-progress-title">工地施工状态</div>
  42. <div class="build-progress-chart">
  43. <ComProgressPieChart :chartData="buildStatusData" v-on="{ fontSize }" />
  44. </div>
  45. </div>
  46. <div class="build-progress-item">
  47. <div class="build-progress-title">清淤检测</div>
  48. <div class="build-progress-chart">
  49. <ComProgressPieChart :chartData="buildDredgingData" v-on="{ fontSize }" />
  50. </div>
  51. </div>
  52. </div>
  53. </div>
  54. <div class="content-item projectInfo">
  55. <div class="title">
  56. <div class="icon"></div>
  57. <span class="item-name">上周项目情况</span>
  58. </div>
  59. <div class="content projectInfoContent">
  60. <div class="top-content">
  61. <div class="chart-container">
  62. <div class="chart-title">完成占比:{{ complishPercent }}</div>
  63. <ComThreeDimensionsChart v-on="{ fontSize }" :chartData="staList" />
  64. <!-- 底座背景 -->
  65. <div class="bg"></div>
  66. </div>
  67. <div class="dataInfo">
  68. <div
  69. class="data-item"
  70. v-for="(item, index) of staList"
  71. :key="item.name"
  72. :style="index === 0 ? 'background: rgba(11, 122, 192,0.16)' : 'background: rgba(8, 178, 114,0.16)'"
  73. >
  74. <div class="pointSymbol" :style="index === 0 ? 'background:#2BA7FF' : 'background:#13D28A'"></div>
  75. <div class="data-title">{{ item.name }}</div>
  76. <div class="data-value">{{ item.value }}{{ item.unit }}</div>
  77. </div>
  78. </div>
  79. </div>
  80. <div class="bottom-content">
  81. <div class="bottom-content-item">
  82. <div class="bc-item">
  83. <div class="bc-title">人员配置</div>
  84. <div class="bc-value">
  85. 总人数:<span>{{ totalPerson }}</span>
  86. </div>
  87. </div>
  88. <div class="bc-item">
  89. <div class="bc-title">设备配置</div>
  90. <div class="bc-value">
  91. 总数量:<span>{{ totalDevice }}</span>
  92. </div>
  93. </div>
  94. </div>
  95. <div class="bottom-content-item">
  96. <div class="bcb-item">
  97. <el-carousel :autoplay="true" direction="vertical">
  98. <el-carousel-item v-for="item in staffingList" :key="item.title">
  99. <div class="bcb-title">{{ item.title }}</div>
  100. <div class="bcb-value">{{ item.value }}{{ item.unit }}</div>
  101. </el-carousel-item>
  102. </el-carousel>
  103. </div>
  104. <div class="bcb-item">
  105. <el-carousel :autoplay="true" direction="vertical">
  106. <el-carousel-item v-for="item in devicesList" :key="item.title">
  107. <div class="bcb-title">{{ item.title }}</div>
  108. <div class="bcb-value">{{ item.value }}{{ item.unit }}</div>
  109. </el-carousel-item>
  110. </el-carousel>
  111. </div>
  112. </div>
  113. </div>
  114. </div>
  115. </div>
  116. </div>
  117. </div>
  118. </transition>
  119. </template>
  120. <script lang="ts">
  121. import { getRequestResult } from '@/views/groupPage/apis'
  122. import { setNullAndUndefinedEmpty, fontSize as fs } from '@/views/groupPage/util'
  123. import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
  124. import ComOneBatteryChart from '@/views/groupPage/components/BatteryChart/ComOneBatteryChart.vue'
  125. import ComProgressChart from '@/views/groupPage/components/BarChart/ComProgressChart.vue'
  126. import ComProgressPieChart from '@/views/groupPage/components/PieChart/ComProgressPieChart.vue'
  127. import ComThreeDimensionsChart from '@/views/groupPage/components/OthersChart/ComThreeDimensionsChart.vue'
  128. //项目进展
  129. @Component({
  130. name: 'ProjectProgress',
  131. components: { ComOneBatteryChart, ComProgressChart, ComProgressPieChart, ComThreeDimensionsChart }
  132. })
  133. export default class ProjectProgress extends Vue {
  134. investData: object = {}
  135. progressData: Array<any> = [{}, {}, {}]
  136. buildStatusData: object = {}
  137. buildDredgingData: object = {}
  138. complishPercent: number = 0 //完成占比
  139. staList: Array<any> = [{}, {}]
  140. totalPerson: number = 0
  141. totalDevice: number = 0
  142. staffingList: Array<any> = []
  143. devicesList: Array<any> = []
  144. get fontSize() {
  145. return fs
  146. }
  147. get setNoNull() {
  148. return setNullAndUndefinedEmpty
  149. }
  150. mounted() {
  151. this.getPageData()
  152. }
  153. roundFun(value, n) {
  154. return Math.round(value * Math.pow(10, n)) / Math.pow(10, n)
  155. }
  156. getPageData() {
  157. let data = { blockCode: 'ycepclist' }
  158. let projectCode = 'HB06'
  159. //获取全部数据
  160. getRequestResult(data).then((res: Array<any>) => {
  161. res = res.filter((item) => item.indexCode.indexOf(projectCode + '-') != -1)
  162. res = res.map((item) => {
  163. Object.keys(item).forEach((val) => (item[val] = item[val] || ''))
  164. return {
  165. ...item,
  166. indexValue:
  167. item.unit === '万'
  168. ? this.roundFun(this.setNoNull(item.indexValue) / 10000, 4)
  169. : this.setNoNull(item.indexValue)
  170. }
  171. })
  172. //投资完成情况
  173. this.investData = {
  174. num: res.find((e) => e.indexCode == projectCode + '-' + 21).indexValue,
  175. numUnit: res.find((e) => e.indexCode == projectCode + '-' + 2).unit,
  176. total: res.find((e) => e.indexCode == projectCode + '-' + 2).indexValue,
  177. totalUnit: res.find((e) => e.indexCode == projectCode + '-' + 2).unit
  178. }
  179. //设计进度
  180. this.progressData = this.progressData.map((item, index) => {
  181. let target = index * 2
  182. return {
  183. name: res.find((e) => e.indexCode == projectCode + '-' + (index + 22)).indexName,
  184. percent:
  185. res.find((e) => e.indexCode == projectCode + '-' + (index + 22)).indexValue +
  186. res.find((e) => e.indexCode == projectCode + '-' + (index + 22)).unit,
  187. totalAmout: res.find((e) => e.indexCode == projectCode + '-' + (target + 25)).indexValue,
  188. finishAmout: res.find((e) => e.indexCode == projectCode + '-' + (target + 26)).indexValue
  189. }
  190. })
  191. //施工进度
  192. this.buildStatusData = {
  193. building: res.find((e) => e.indexCode == projectCode + '-' + 31).indexValue,
  194. finished: res.find((e) => e.indexCode == projectCode + '-' + 32).indexValue,
  195. nobuilding: res.find((e) => e.indexCode == projectCode + '-' + 33).indexValue,
  196. unit: res.find((e) => e.indexCode == projectCode + '-' + 31).unit
  197. }
  198. this.buildDredgingData = {
  199. building: res.find((e) => e.indexCode == projectCode + '-' + 34).indexValue,
  200. finished: 0,
  201. nobuilding: res.find((e) => e.indexCode == projectCode + '-' + 35).indexValue,
  202. unit: res.find((e) => e.indexCode == projectCode + '-' + 34).unit
  203. }
  204. //上周项目情况
  205. this.complishPercent =
  206. res.find((e) => e.indexCode == projectCode + '-' + 38).indexValue +
  207. res.find((e) => e.indexCode == projectCode + '-' + 38).unit
  208. this.staList = this.staList.map((item, index) => {
  209. return {
  210. name: res.find((e) => e.indexCode == projectCode + '-' + (index + 36)).indexName,
  211. value: res.find((e) => e.indexCode == projectCode + '-' + (index + 36)).indexValue,
  212. unit: '亿'
  213. }
  214. })
  215. //
  216. this.totalPerson = res.find((e) => e.indexCode == projectCode + '-' + +39).indexValue
  217. this.totalDevice = res.find((e) => e.indexCode == projectCode + '-' + +40).indexValue
  218. res
  219. .filter((item) => item.indexCode.indexOf(projectCode + '-' + '40') != -1)
  220. .forEach((citem) => {
  221. this.staffingList.push({
  222. title: citem.indexName,
  223. value: citem.indexValue,
  224. unit: citem.unit
  225. })
  226. })
  227. res
  228. .filter((item) => item.indexCode.indexOf(projectCode + '-' + '44') != -1)
  229. .forEach((citem) => {
  230. this.devicesList.push({
  231. title: citem.indexName,
  232. value: citem.indexValue,
  233. unit: citem.unit
  234. })
  235. })
  236. })
  237. }
  238. }
  239. </script>
  240. <style lang='scss' scoped>
  241. .animate__slideInRight,
  242. .animate__slideOutRight {
  243. animation-duration: 3s; //动画持续时间
  244. animation-delay: 0s; //动画延迟时间
  245. }
  246. .widget-ProjectProgress {
  247. $size10: 0.052083rem /* 10/192 */;
  248. $size20: 0.104167rem /* 20/192 */;
  249. z-index: 2;
  250. //position
  251. bottom: $size10 /* 10/192 */;
  252. margin-right: $size20 /* 20/192 */;
  253. right: 0;
  254. position: absolute;
  255. //size
  256. height: calc(100% - 0.557292rem /* 107/192 */);
  257. width: 2.083333rem /* 400/192 */;
  258. color: #eee;
  259. .head {
  260. height: 0.166667rem /* 32/192 */;
  261. width: 100%;
  262. background: linear-gradient(-90deg, rgba(43, 167, 255, 0.2) 0%, rgba(43, 167, 255, 0.08) 100%);
  263. font-family: Source Han Sans CN-HEAVY;
  264. .title {
  265. width: 100%;
  266. height: 100%;
  267. display: flex;
  268. font-weight: 400;
  269. align-items: center;
  270. .icon {
  271. height: 0.166667rem /* 32/192 */;
  272. width: 0.34375rem /* 66/192 */;
  273. background: url('~@/views/groupPage/images/模块图标/项目进展.png') no-repeat center center;
  274. background-size: 100% 100%;
  275. }
  276. span {
  277. flex: 1;
  278. font-weight: bold;
  279. font-size: 0.083333rem /* 16/192 */;
  280. color: #ffffff;
  281. padding: 0.041667rem /* 8/192 */;
  282. background: linear-gradient(0deg, #9bd2fa 0%, #ffffff 100%);
  283. background-clip: text;
  284. -webkit-text-fill-color: transparent;
  285. }
  286. }
  287. }
  288. .content-info {
  289. width: 100%;
  290. height: calc(100% - 0.166667rem);
  291. overflow: auto;
  292. padding: 2px;
  293. .investment {
  294. height: 15% !important;
  295. }
  296. .projectInfo {
  297. height: 35% !important;
  298. }
  299. .content-item {
  300. width: 100%;
  301. height: 25%;
  302. float: left;
  303. overflow: hidden;
  304. .title {
  305. width: 100%;
  306. display: flex;
  307. // padding: .145833rem 0 .104167rem 0;
  308. padding: 0.145833rem 0 0.026042rem /* 5/192 */ 0;
  309. .icon {
  310. height: 0.072917rem /* 14/192 */;
  311. width: 0.078125rem /* 15/192 */;
  312. margin-right: 0.046875rem /* 9/192 */;
  313. background: url('~@/views/groupPage/images/三角.png') no-repeat center center;
  314. background-size: 100% 100%;
  315. }
  316. .item-name {
  317. font-family: Source Han Sans CN;
  318. color: #0ea7ff;
  319. font-size: 0.072917rem /* 14/192 */;
  320. font-weight: 500;
  321. }
  322. .item-info {
  323. color: #2ba7ff;
  324. font-size: 0.072917rem /* 14/192 */;
  325. font-weight: 500;
  326. }
  327. }
  328. .content {
  329. height: calc(100% - 0.234375rem /* 45/192 */);
  330. width: 100%;
  331. display: flex;
  332. }
  333. .build-progress {
  334. justify-content: space-between;
  335. }
  336. .build-progress-item {
  337. height: 100%;
  338. width: 48%;
  339. background: rgba(43, 167, 255, 0.16);
  340. .build-progress-title {
  341. display: flex;
  342. justify-content: center;
  343. padding: 0.052083rem /* 10/192 */;
  344. font-size: 0.072917rem /* 14/192 */;
  345. font-family: Source Han Sans CN;
  346. font-weight: 500;
  347. color: #ffffff;
  348. }
  349. .build-progress-chart {
  350. width: 100%;
  351. height: calc(100% - 0.177083rem /* 34/192 */);
  352. }
  353. }
  354. .projectInfoContent {
  355. flex-flow: column;
  356. }
  357. .top-content {
  358. display: flex;
  359. height: 50%;
  360. width: 100%;
  361. }
  362. .chart-container {
  363. width: 50%;
  364. position: relative;
  365. .chart-title {
  366. position: absolute;
  367. left: 0.234375rem /* 45/192 */;
  368. font-size: 0.083333rem /* 16/192 */;
  369. font-family: Source Han Sans CN;
  370. font-weight: bold;
  371. top: 0.104167rem /* 20/192 */;
  372. color: #ffffff;
  373. white-space: normal;
  374. }
  375. .bg {
  376. width: 100%;
  377. height: 100%;
  378. }
  379. .bg {
  380. position: absolute;
  381. top: 0;
  382. left: 0;
  383. right: 0;
  384. margin: 0 auto;
  385. width: 70%;
  386. width: 55%;
  387. height: 95%;
  388. // left: 0.041667rem /* 8/192 */;
  389. z-index: -1;
  390. // width: 0.46875rem /* 90/192 */;
  391. // height: 0.390625rem /* 75/192 */;
  392. background: no-repeat center;
  393. background-image: url('~@/views/groupPage/images/底座样式.png');
  394. background-size: 100% 100%;
  395. }
  396. }
  397. .dataInfo {
  398. width: 50%;
  399. display: flex;
  400. flex-flow: column;
  401. justify-content: space-around;
  402. font-family: Source Han Sans CN;
  403. .data-item {
  404. display: flex;
  405. align-items: center;
  406. padding: 0.052083rem /* 10/192 */;
  407. color: #ffffff;
  408. height: 45%;
  409. .pointSymbol,
  410. .data-title {
  411. margin-right: 0.052083rem /* 10/192 */;
  412. white-space: nowrap;
  413. }
  414. .pointSymbol {
  415. border-radius: 50%;
  416. height: 0.052083rem /* 10/192 */;
  417. width: 0.052083rem /* 10/192 */;
  418. }
  419. .data-title {
  420. font-size: 0.072917rem /* 14/192 */;
  421. font-weight: 400;
  422. color: #ffffff;
  423. }
  424. .data-value {
  425. font-size: 0.083333rem /* 16/192 */;
  426. font-family: Source Han Sans CN-HEAVY;
  427. font-weight: bold;
  428. color: #ffffff;
  429. position: absolute;
  430. right: 2%;
  431. }
  432. }
  433. }
  434. .bottom-content {
  435. height: 50%;
  436. width: 100%;
  437. display: flex;
  438. flex-flow: column;
  439. justify-content: space-between;
  440. margin-top: 0.052083rem /* 10/192 */;
  441. .bottom-content-item {
  442. height: 45%;
  443. width: 100%;
  444. display: flex;
  445. justify-content: space-between;
  446. align-items: center;
  447. font-family: Source Han Sans CN;
  448. .bc-item {
  449. height: 100%;
  450. width: 48%;
  451. background: rgba(14, 167, 255, 0.14);
  452. display: flex;
  453. justify-content: space-around;
  454. align-items: center;
  455. .bc-title {
  456. font-size: 0.072917rem /* 14/192 */;
  457. font-weight: 500;
  458. color: #2ba7ff;
  459. }
  460. .bc-value {
  461. font-size: 0.072917rem /* 14/192 */;
  462. font-weight: 400;
  463. color: rgba(139, 191, 228, 1);
  464. & > span {
  465. font-family: Source Han Sans CN-HEAVY;
  466. font-weight: bold;
  467. color: rgba(43, 167, 255, 1);
  468. }
  469. }
  470. }
  471. .bcb-item {
  472. height: 100%;
  473. width: 48%;
  474. background: rgba(255, 255, 255, 0.1);
  475. /deep/ .el-carousel {
  476. height: 100%;
  477. width: 100%;
  478. .el-carousel__container {
  479. height: inherit;
  480. width: inherit;
  481. .el-carousel__item {
  482. display: flex;
  483. justify-content: space-around;
  484. align-items: center;
  485. }
  486. }
  487. .el-carousel__indicators {
  488. display: none;
  489. }
  490. .bcb-title {
  491. font-size: 0.072917rem /* 14/192 */;
  492. font-weight: 400;
  493. color: #ffffff;
  494. }
  495. .bcb-value {
  496. font-size: 0.072917rem /* 14/192 */;
  497. font-weight: 500;
  498. color: #ffffff;
  499. }
  500. }
  501. }
  502. }
  503. }
  504. }
  505. }
  506. }
  507. </style>