| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596 |
- <template>
- <transition
- appear
- name="animate__animated animate__move"
- enter-active-class="animate__slideInRight"
- leave-active-class="animate__slideOutRight"
- >
- <div class="widget-ProjectProgress">
- <div class="head">
- <div class="title">
- <div class="icon"></div>
- <span class="site-info">项目进展</span>
- </div>
- </div>
- <div class="content-info">
- <!-- -->
- <div class="content-item progress">
- <div class="title">
- <div class="icon"></div>
- <span class="item-name">施工情况</span>
- </div>
- <div class="content contruct-content">
- {{ contructContent }}
- </div>
- </div>
- <!-- -->
- <div class="content-item settlement">
- <div class="title">
- <div class="icon"></div>
- <span class="item-name">本年结算情况</span>
- </div>
- <div class="content">
- <div class="chart-container">
- <ComRightAngelPercentChart :value="0" />
- </div>
- <div class="dataInfo">
- <div class="data-item" v-for="(item, index) of settleList" :key="item.name">
- <div
- class="pointSymbol"
- :style="index == 0 ? 'background:#2BA7FF;box-shadow: 0px 0px 10px #2BA7FF;' : ''"
- ></div>
- <div class="data-wrap">
- <div class="data-title">{{ item.name }}</div>
- <div class="data-value data-value-settle">{{ item.value }} {{ item.unit }}</div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- -->
- <div class="content-item outputValue">
- <div class="title">
- <div class="icon"></div>
- <span class="item-name">建管本年产值统计</span>
- </div>
- <div class="content">
- <div class="chart-container">
- <div class="chart-title">
- 完成占比:<span>{{ complishPercent }}%</span>
- </div>
- <ComThreeDimensionsChart v-on="{ fontSize }" :chartData="staList" :distance="150" />
- <!-- 底座背景 -->
- <div class="bg" :style="{ 'background-image': `url('${url}')` }"></div>
- </div>
- <div class="dataInfo">
- <div class="data-item" v-for="(item, index) of staList" :key="item.name">
- <div
- class="pointSymbol"
- :style="index == 0 ? 'background:#13D28A;box-shadow: 0px 0px 10px #13D28A;' : ''"
- ></div>
- <div class="data-wrap">
- <div class="data-title">{{ item.name }}</div>
- <div class="data-value">{{ item.value }} {{ item.unit }}</div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- -->
- <div class="content-item outputValueSta">
- <div class="title">
- <div class="icon"></div>
- <span class="item-name">建管本年产值统计</span>
- </div>
- <div class="content OVSContent">
- <div class="bc-item">
- <div class="bc-title">人员配置</div>
- <div class="bc-value">
- 总人数:<span>{{ totalPerson }}</span>
- </div>
- </div>
- <div class="bc-content">
- <div class="bcb-item" v-for="item in staffingList" :key="item.title">
- <div class="bcb-title">{{ item.title }}</div>
- <div class="bcb-value">{{ item.value }}{{ item.unit }}</div>
- </div>
- </div>
- <div class="bc-item">
- <div class="bc-title">设备配置</div>
- <div class="bc-value">
- 总数量:<span>{{ totalDevice }}</span>
- </div>
- </div>
- <div class="bcb-content">
- <el-carousel :autoplay="true" direction="vertical">
- <el-carousel-item v-for="(part, index) in devicesList" :key="index">
- <div class="bcbc-item" v-for="item in part.list" :key="item.title">
- <div class="bcbc-title">{{ item.title }}</div>
- <div class="bcbc-value">{{ item.value }}{{ item.unit }}</div>
- </div>
- </el-carousel-item>
- </el-carousel>
- </div>
- </div>
- </div>
- </div>
- </div>
- </transition>
- </template>
- <script lang="ts">
- import url from '../../images/base64/3dBaseBack'
- import { getRequestResult, getEpcBuilding, getWeekCountData } from '../../apis'
- import { setNullAndUndefinedEmpty, fontSize as fs } from '../../util'
- import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
- import ComOneBatteryChart from '../../components/BatteryChart/ComOneBatteryChart.vue'
- import ComProgressChart from '../../components/BarChart/ComProgressChart.vue'
- import ComProgressPieChart from '../../components/PieChart/ComProgressPieChart.vue'
- import ComThreeDimensionsChart from '../../components/OthersChart/ComThreeDimensionsChart.vue'
- import ComRightAngelPercentChart from '../../components/PieChart/ComRightAngelPercentChart.vue'
- const staffTypeList = [
- { code: 'person_all', name: '总包部' },
- { code: 'person_build', name: '建设部' },
- { code: 'person_survey', name: '勘察单位' },
- { code: 'person_design', name: '设计单位' },
- { code: 'person_construct', name: '施工单位' }
- ]
- const deviceTypeList = [
- { code: 'device_gdjc', name: '管道检修设备' },
- { code: 'device_kw', name: '开挖设备' },
- { code: 'device_other', name: '其他设备' },
- { code: 'device_cl', name: '测量设备' },
- { code: 'device_fdj', name: '发电机' },
- { code: 'device_dj', name: '地基处理设备' },
- { code: 'device_zh', name: '支护设备' },
- { code: 'device_tz', name: '填筑设备' },
- { code: 'device_ly', name: '拉运设备' }
- ]
- //项目进展
- @Component({
- name: 'ProjectProgress',
- components: {
- ComOneBatteryChart,
- ComProgressChart,
- ComProgressPieChart,
- ComThreeDimensionsChart,
- ComRightAngelPercentChart
- }
- })
- export default class ProjectProgress extends Vue {
- @Prop({ type: Object, default: () => {} }) dataInfo!: any
- url = url
- investData: object = {}
- contructContent: string = ''
- progressData: Array<any> = [{}, {}, {}]
- buildStatusData: object = {}
- buildDredgingData: object = {}
- complishPercent: number = 0 //完成占比
- settleList: Array<any> = [{}, {}]
- staList: Array<any> = [{}, {}]
- totalPerson: number = 0
- totalDevice: number = 0
- staffingList: Array<any> = []
- devicesList: Array<any> = []
- get fontSize() {
- return fs
- }
- get setNoNull() {
- return setNullAndUndefinedEmpty
- }
- get projectCode() {
- return this.$store.state.bigScreen.currentProjectCode
- }
- roundFun(value, n) {
- return Math.round(value * Math.pow(10, n)) / Math.pow(10, n)
- }
- reset() {
- this.staffingList = []
- this.devicesList = []
- }
- @Watch('dataInfo')
- onChangMehod() {
- this.getPageData()
- }
- async getPageData() {
- this.reset()
- if (!this.dataInfo) return
- const { contract_epc_money, contract_ppp_money } = this.dataInfo || {}
- //投资完成情况
- this.investData = {
- num: this.roundFun(contract_epc_money / 10 ** 8, 4),
- numUnit: '亿',
- total: this.roundFun(contract_ppp_money / 10 ** 8, 4),
- totalUnit: '亿'
- }
- //获取施工状态
- this.getBuildStatusData()
- //周报统计
- const weekCountData = await getWeekCountData({ code: this.projectCode })
- const wcd = weekCountData.result
- if (!wcd) return
- const { year_finish_ratio, year_finish, year_plan, contruct_content } = wcd || {}
- this.contructContent = contruct_content
- this.complishPercent = year_finish_ratio
- this.staList = [
- { name: '本年完成产值', value: +year_finish, unit: '万元' },
- { name: '年度产值计划', value: +year_plan, unit: '万元' }
- ]
- this.settleList = [
- { name: '本年投资计划', value: 0, unit: '万元' },
- { name: '本年结算金额', value: 0, unit: '万元' }
- ]
- let staff = [],
- devices = []
- for (const key in wcd) {
- if (key.includes('person_') && key != 'person_num') {
- staff.push(this.assembleStuff(key, wcd))
- }
- if (key.includes('device_') && key != 'device_num') {
- devices.push(this.assembleDevice(key, wcd))
- }
- }
- this.staffingList = staff
- this.totalPerson = this.countTotal(staff, 'value')
- this.devicesList = this.splitArr(devices, 4)
- this.totalDevice = this.countTotal(devices, 'value')
- }
- splitArr(res, splitNum = 5) {
- let temp = [],
- symbol = 0
- res.forEach((item: any, index) => {
- if ((index + 1) % splitNum != 0) {
- temp[symbol] ? temp[symbol].list.push({ ...item }) : temp.push({ list: [{ ...item }] })
- } else {
- temp[symbol].list.length < splitNum ? temp[symbol].list.push({ ...item }) : temp.push({ list: [{ ...item }] })
- symbol++
- }
- })
- return temp
- }
- countTotal(arr, keyName) {
- let total = 0
- total = arr.reduce(function (total, currentValue, currentIndex, arr) {
- return currentValue[keyName] ? total + currentValue[keyName] : total
- }, 0)
- return total
- }
- assembleStuff(key, obj) {
- let target: any = staffTypeList.find((i) => i.code == key) || {}
- return { title: target.name, value: +obj[key], unit: '人' }
- }
- assembleDevice(key, obj) {
- let target: any = deviceTypeList.find((i) => i.code == key) || {}
- return { title: target.name, value: +obj[key], unit: '台' }
- }
- //施工状态
- async getBuildStatusData() {
- const buildStatusData = await getEpcBuilding({ code: this.projectCode })
- if (buildStatusData.result.length == 0) return
- const bsd = buildStatusData.result
- this.buildStatusData = {
- building: bsd.filter((i) => i.node_status == 'doing').length,
- finished: bsd.filter((i) => i.node_status == 'done').length,
- nobuilding: bsd.filter((i) => i.node_status == 'normal').length,
- unit: '总作业面'
- }
- }
- }
- </script>
- <style lang='scss' scoped>
- .animate__slideInRight,
- .animate__slideOutRight {
- animation-duration: 3s; //动画持续时间
- animation-delay: 0s; //动画延迟时间
- }
- .widget-ProjectProgress {
- $size10: 0.052083rem /* 10/192 */;
- $size20: 0.104167rem /* 20/192 */;
- z-index: 2;
- //position
- bottom: $size10 /* 10/192 */;
- margin-right: $size20 /* 20/192 */;
- right: 0;
- position: absolute;
- //size
- height: calc(100% - 0.557292rem /* 107/192 */);
- width: 2.083333rem /* 400/192 */;
- color: #eee;
- .head {
- height: 0.166667rem /* 32/192 */;
- width: 100%;
- background: linear-gradient(-90deg, rgba(43, 167, 255, 0.2) 0%, rgba(43, 167, 255, 0.08) 100%);
- font-family: Source Han Sans CN-HEAVY;
- .title {
- width: 100%;
- height: 100%;
- display: flex;
- font-weight: 400;
- align-items: center;
- .icon {
- height: 0.166667rem /* 32/192 */;
- width: 0.34375rem /* 66/192 */;
- background: url('~@/views/groupPage/images/模块图标/项目进展.png') no-repeat center center;
- background-size: 100% 100%;
- }
- span {
- flex: 1;
- font-weight: bold;
- font-size: 0.083333rem /* 16/192 */;
- color: #ffffff;
- padding: 0.041667rem /* 8/192 */;
- background: linear-gradient(0deg, #9bd2fa 0%, #ffffff 100%);
- background-clip: text;
- -webkit-text-fill-color: transparent;
- }
- }
- }
- .content-info {
- width: 100%;
- height: calc(100% - 0.166667rem);
- overflow: auto;
- .content-item {
- margin-top: 0.052083rem /* 10/192 */;
- padding: 0.088542rem /* 17/192 */ 0.046875rem /* 9/192 */ 0.083333rem /* 16/192 */ 0.046875rem /* 9/192 */;
- width: 100%;
- float: left;
- overflow: hidden;
- background: linear-gradient(0deg, rgba(14, 167, 255, 0.1) 0%, rgba(14, 167, 255, 0.1) 100%);
- .title {
- width: 100%;
- display: flex;
- margin-bottom: 0.0625rem /* 12/192 */;
- .icon {
- height: 0.072917rem /* 14/192 */;
- width: 0.078125rem /* 15/192 */;
- margin-right: 0.046875rem /* 9/192 */;
- background: url('~@/views/groupPage/images/三角.png') no-repeat center center;
- background-size: 100% 100%;
- }
- .item-name {
- font-family: Source Han Sans CN;
- color: #0ea7ff;
- font-size: 0.072917rem /* 14/192 */;
- font-weight: 500;
- }
- .item-info {
- color: #2ba7ff;
- font-size: 0.072917rem /* 14/192 */;
- font-weight: 500;
- }
- }
- .content {
- height: calc(100% - 0.125rem /* 24/192 */);
- width: 100%;
- display: flex;
- }
- .contruct-content {
- overflow: auto;
- text-indent: 1cm; //28px
- color: #feffff;
- font-family: Source Han Sans CN;
- font-size: 0.07292rem;
- line-height: 0.109375rem /* 21/192 */;
- word-break: break-all;
- }
- .chart-container {
- width: 50%;
- position: relative;
- .chart-title {
- position: absolute;
- left: 0.15625rem /* 30/192 */;
- font-size: 0.083333rem /* 16/192 */;
- font-family: Source Han Sans CN;
- font-weight: bold;
- top: 0.052083rem /* 10/192 */;
- color: #ffffff;
- white-space: normal;
- span {
- font-family: AgencyFB-Bold;
- font-weight: bold;
- font-size: 0.104167rem /* 20/192 */;
- }
- }
- .bg {
- width: 100%;
- height: 100%;
- }
- .bg {
- position: absolute;
- top: 0;
- left: -0.026042rem /* 5/192 */;
- right: 0;
- margin: 0 auto;
- width: 80%;
- // width: 55%;
- // height: 95%;
- // left: 0.041667rem /* 8/192 */;
- z-index: -1;
- // width: 0.46875rem /* 90/192 */;
- // height: 0.390625rem /* 75/192 */;
- background: no-repeat center;
- // background-image: url('~@/views/groupPage/images/底座样式.png');
- background-size: 100% 100%;
- }
- }
- .dataInfo {
- width: 50%;
- display: flex;
- flex-flow: column;
- justify-content: space-around;
- font-family: Source Han Sans CN;
- .data-item {
- display: flex;
- align-items: center;
- padding: 0.052083rem /* 10/192 */;
- color: #ffffff;
- height: 45%;
- position: relative;
- .pointSymbol,
- .data-title {
- margin-right: 0.052083rem /* 10/192 */;
- white-space: nowrap;
- }
- .pointSymbol {
- border-radius: 50%;
- height: 0.052083rem /* 10/192 */;
- width: 0.052083rem /* 10/192 */;
- }
- .data-wrap {
- display: flex;
- flex-flow: column;
- }
- .data-title {
- font-size: 0.072917rem /* 14/192 */;
- font-weight: 400;
- color: #87bfe8;
- }
- .data-value {
- font-size: 0.09375rem /* 18/192 */;
- font-family: AgencyFB-Bold;
- font-weight: bold;
- // color: #ffffff;
- padding: 0.052083rem /* 10/192 */ 0;
- }
- }
- .data-item:first-child {
- .data-value {
- color: #13d28a;
- background: linear-gradient(0deg, #01b174 0%, #35ffcb 100%);
- background-clip: text;
- -webkit-text-fill-color: transparent;
- }
- .data-value-settle {
- color: #12d3ff;
- background: linear-gradient(180deg, #50d6fd 0%, #2d92fa 100%);
- background-clip: text;
- -webkit-text-fill-color: transparent;
- }
- }
- .data-item:first-child::after {
- content: '';
- height: 0.005208rem /* 1/192 */;
- width: 90%;
- background: rgba(11, 122, 192, 0.3);
- left: 0;
- right: 0;
- bottom: 0;
- margin: 0 auto;
- position: absolute;
- }
- }
- .OVSContent {
- width: 100%;
- height: calc(100% - 0.135417rem /* 26/192 */);
- display: flex;
- flex-flow: column;
- .bc-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
- width: 100%;
- height: 0.208333rem /* 40/192 */;
- background: rgba(14, 167, 255, 0.14);
- padding: 0.052083rem /* 10/192 */;
- margin-bottom: 0.03125rem /* 6/192 */;
- .bc-title {
- font-size: 0.072917rem /* 14/192 */;
- font-weight: 500;
- color: #2ba7ff;
- }
- .bc-value {
- font-size: 0.072917rem /* 14/192 */;
- font-weight: 400;
- color: rgba(139, 191, 228, 1);
- & > span {
- font-family: AgencyFB-Bold;
- font-weight: bold;
- color: rgba(43, 167, 255, 1);
- }
- }
- }
- .bc-content {
- height: 0.3125rem /* 60/192 */;
- width: 100%;
- background: rgba(255, 255, 255, 0.1);
- margin-bottom: 0.052083rem /* 10/192 */;
- display: flex;
- justify-content: space-around;
- .bcb-item {
- height: 100%;
- display: flex;
- flex-flow: column;
- justify-content: space-around;
- .bcb-title {
- font-size: 0.072917rem /* 14/192 */;
- font-weight: 400;
- color: #ffffff;
- }
- .bcb-value {
- font-size: 0.072917rem /* 14/192 */;
- font-weight: 500;
- color: #ffffff;
- text-align: center;
- }
- }
- }
- .bcb-content {
- width: 100%;
- height: 0.442708rem /* 85/192 */;
- overflow: auto;
- /deep/ .el-carousel {
- height: 100%;
- width: 100%;
- .el-carousel__container {
- height: inherit;
- width: inherit;
- }
- .el-carousel__indicators {
- display: none;
- }
- }
- .bcbc-item {
- width: calc(50% - 0.020833rem /* 4/192 */);
- height: 0.208333rem /* 40/192 */;
- background: rgba(255, 255, 255, 0.1);
- float: left;
- margin-bottom: 0.026042rem /* 5/192 */;
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 0 0.052083rem /* 10/192 */;
- font-size: 0.072917rem /* 14/192 */;
- color: #ffffff;
- .bcbc-title {
- font-family: Source Han Sans CN;
- font-weight: 400;
- }
- .bcbc-value {
- font-family: Source Han Sans CN-MEDIUM;
- font-weight: 500;
- }
- }
- .bcbc-item:nth-child(odd) {
- margin-right: 0.041667rem /* 8/192 */;
- }
- }
- }
- }
- .progress {
- // height: 0.859375rem /* 165/192 */ !important;
- height: calc(100% - 3.666667rem /* 704/192 */) !important;
- }
- .settlement,
- .outputValue {
- height: 0.9375rem /* 180/192 */ !important;
- }
- .outputValueSta {
- // height: calc(100% - 3.151042rem /* 605/192 */) !important;
- height: 1.583333rem /* 304/192 */ !important;
- }
- }
- }
- </style>
|