| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- <template>
- <div class="w-full h-full relative flex justify-between items-center">
- <!-- 左侧面板 -->
- <Panel>
- <CardTitle>项目倒计时</CardTitle>
- <div class="w-full flex flex-row gap-10px pt-10px mb-10px">
- <div class="flex flex-col">
- <div class="p-5px flex flex-row justify-center items-center bg-[#348bc74c] w-200px">
- <div class="backgroundImages w-70px h-70px flex justify-center items-center">
- <img src="@/assets/images/u1407.svg" />
- </div>
- <div class="ml-10px">
- <div class="text-15px color-[#ffffffb2]">合同开工日期</div>
- <div class="text-20px mt-10px">{{ dataSource?.xmdjs?.start_time }}</div>
- </div>
- </div>
- <div
- class="p-5px flex flex-row justify-center items-center bg-[#348bc74c] mt-10px w-200px"
- >
- <div class="backgroundImages w-70px h-70px flex justify-center items-center">
- <img src="@/assets/images/u1420.svg" />
- </div>
- <div class="ml-10px">
- <div class="text-15px color-[#ffffffb2]">合同结束日期</div>
- <div class="text-20px mt-10px">{{ dataSource?.xmdjs?.end_time }}</div>
- </div>
- </div>
- </div>
- <div class="bg-[#348bc74c] w-211px flex flex-col justify-center items-center">
- <DigitalFlop :config="config5" />
- <div class="text-17px color-[#ffffffb2]">剩余天数</div>
- </div>
- </div>
- <CardTitle>WBS分解</CardTitle>
- <div class="text-white h-350px w-full pt-10px left-bottom-board">
- <ScrollBoard :config="config1" @mouseover="mouseoverHandler" @click="clickHandler" />
- </div>
- <CardTitle>CWS分解</CardTitle>
- <div class="w-full h-260px flex gap-10px p-10px box-border justify-between items-center left-bottom-board">
- <ScrollBoard :config="config2" @mouseover="mouseoverHandler" @click="clickHandler" />
- </div>
- </Panel>
- <!-- 中间区域 -->
- <!-- <div
- class="h-full box-border pr-10px pl-10px middle-content flex-1 flex flex-col gap-10px justify-center"
- >
- <div class="text-white h-500px w-full center-board">
- <ProjectMilestone />
- </div>
- </div> -->
- <!-- 右侧面板 -->
- <Panel>
- <div class="bg-[#348bc74c] w-full h-150px flex flex-col justify-center items-center">
- <DigitalFlop :config="config6" style="height: 80px; width: 100%" />
- <div class="text-32px color-[#ffffffb2]">实际AC</div>
- </div>
- <CardTitle>单体完成比率统计</CardTitle>
- <div class="text-white h-350px w-full center-board right-top-board">
- <Chart :options="chartOptionsRightTop" />
- </div>
- <CardTitle>单体-分部完成比率统计</CardTitle>
- <div class="w-full box-border p-10px h-350px">
- <Chart :options="chartOptionsRightBottom" />
- </div>
- </Panel>
- </div>
- </template>
- <script setup lang="ts">
- import { ref, computed, inject } from 'vue';
- import { ScrollBoard, DigitalFlop } from '@kjgl77/datav-vue3';
- import Panel from '@/components/Panel.vue';
- import CardTitle from '@/components/CardTitle.vue';
- import Chart from '@/components/Chart/index.vue';
- import type { EChartsOption } from 'echarts';
- import { invoke } from '@/api';
- import { useRequest } from 'vue-hooks-plus';
- import type { Ref } from 'vue';
- const projectCode = inject<Ref<string[]>>('projectCode');
- const dataSource = ref<{
- // ac
- ac: string;
- // 项目倒计时
- xmdjs: {
- // 结束时间
- end_time: string;
- // 开始时间
- start_time: string;
- // 工期
- days: number;
- };
- // wbs分解
- wbsfj: [
- {
- // 状态
- tas_state: string;
- // 分类
- tas_classify: string;
- // 单体
- tas_monomer: string;
- },
- ];
- // 单体完成比率
- dtwcbl: [
- {
- // 标题
- title: string;
- // 完成比例
- value: number;
- },
- ];
- // cws分解
- cwsfj: [
- {
- // 状态
- tas_state: string;
- // 分类
- tas_classify: string;
- // 单体预算金额(万元)
- tas_budget_amount: number;
- // 单体
- tas_monomer: number;
- },
- ];
- // 单体-分部完成比率统计
- dtbfbl: [
- {
- // 标题
- title: string;
- // 完成比例
- value: number;
- },
- ];
- }>();
- useRequest(invoke, {
- defaultParams: [
- {
- // 固定值
- interfaceCode: 'BigScreen.progressManagement',
- // 编号代码
- projectCode: projectCode?.value?.[1],
- },
- ],
- onSuccess(res: any) {
- dataSource.value = res;
- },
- pollingInterval: 10000
- });
- const config1 = computed(() => {
- const list = dataSource.value?.wbsfj || [];
- return {
- header: ['单体', '当前状态', '所属分类'],
- data: list.map((item) => [item.tas_monomer, item.tas_state, item.tas_classify]),
- headerBGC: '#348bc763',
- evenRowBGC: 'rgba(29, 66, 110, 0.6)',
- oddRowBGC: 'rgba(52, 139, 199, 0.0980392156862745)',
- align: ['center'],
- index: true,
- columnWidth: [50],
- rowNum: 6,
- headerHeight: 35,
- waitTime: 50005000,
- };
- });
- const config5 = computed(() => {
- return {
- number: [dataSource.value?.xmdjs?.days || 0],
- content: '{nt}%',
- };
- });
- const config6 = computed(() => {
- return {
- number: [dataSource.value?.ac || 0],
- content: '{nt}',
- };
- });
- let currentZoom = { start: 0, end: 50 };
- const config2 = computed(() => {
- const list = dataSource.value?.cwsfj || [];
- return {
- header: ['单体', '当前状态', '所属分类', '预算金额(万元)'],
- data: list.map((item) => [
- item.tas_monomer,
- item.tas_state,
- item.tas_classify,
- item.tas_budget_amount,
- ]),
- headerBGC: '#348bc763',
- evenRowBGC: 'rgba(29, 66, 110, 0.6)',
- oddRowBGC: 'rgba(52, 139, 199, 0.0980392156862745)',
- align: ['center'],
- index: true,
- columnWidth: [50],
- rowNum: 6,
- headerHeight: 35,
- waitTime: 50005000,
- };
- });
- // 右侧顶部柱状图
- // let scrollIntervalRightTop: ReturnType<typeof setInterval>;
- // let currentZoomeRightTop = { start: 0, end: 50 };
- const chartOptionsRightTop = computed((): EChartsOption => {
- const list = dataSource.value?.dtbfbl || [];
- return {
- tooltip: {
- trigger: 'item',
- textStyle: { color: '#000' },
- },
- xAxis: {
- type: 'value',
- axisLabel: { color: '#fff' },
- },
- yAxis: {
- type: 'category',
- data: list.map((item) => item.title),
- axisLabel: { color: '#fff' },
- },
- series: [
- {
- name: '进度',
- type: 'bar',
- data: list.map((item) => item.value),
- barWidth: 16,
- itemStyle: {
- color: 'rgba(42, 254, 255, 1)',
- borderRadius: [4, 4, 4, 4],
- },
- label: {
- show: true,
- position: 'right',
- color: '#fff',
- fontSize: 10,
- },
- },
- ],
- grid: {
- top: '5%',
- left: '3%',
- right: '4%',
- bottom: '3%',
- containLabel: true,
- },
- dataZoom: [
- {
- show: false,
- type: 'slider',
- yAxisIndex: 0,
- start: currentZoom.start,
- end: currentZoom.end,
- },
- ],
- };
- });
- // const startAutoScrollRightTop = () => {
- // clearInterval(scrollIntervalRightTop);
- // scrollIntervalRightTop = setInterval(() => {
- // if (currentZoomeRightTop.end >= 100) {
- // currentZoomeRightTop.start = 0;
- // currentZoomeRightTop.end = 50;
- // } else {
- // currentZoomeRightTop.start += 2;
- // currentZoomeRightTop.end += 2;
- // }
- // chartOptionsRightTop.value = {
- // ...chartOptionsRightTop.value,
- // dataZoom: [
- // {
- // show: false,
- // type: 'slider',
- // yAxisIndex: 0,
- // start: currentZoomeRightTop.start,
- // end: currentZoomeRightTop.end,
- // },
- // ],
- // };
- // }, 2000);
- // };
- // 右侧底部
- // let scrollIntervalRightBottom: ReturnType<typeof setInterval>;
- // let currentZoomeRightBottom = { start: 0, end: 50 };
- const chartOptionsRightBottom = computed((): EChartsOption => {
- const list = dataSource.value?.dtbfbl || [];
- return {
- tooltip: {
- trigger: 'item',
- textStyle: { color: '#000' },
- },
- xAxis: {
- type: 'value',
- axisLabel: { color: '#fff' },
- },
- yAxis: {
- type: 'category',
- data: list.map((item) => item.title),
- axisLabel: { color: '#fff' },
- },
- series: [
- {
- name: '进度',
- type: 'bar',
- data: list.map((item) => item.value),
- barWidth: 16,
- itemStyle: {
- color: 'rgba(42, 254, 255, 1)',
- borderRadius: [4, 4, 4, 4],
- },
- label: {
- show: true,
- position: 'right',
- color: '#fff',
- fontSize: 10,
- },
- },
- ],
- grid: {
- top: '5%',
- left: '3%',
- right: '4%',
- bottom: '3%',
- containLabel: true,
- },
- dataZoom: [
- {
- show: false,
- type: 'slider',
- yAxisIndex: 0,
- start: currentZoom.start,
- end: currentZoom.end,
- },
- ],
- }
- });
- // const startAutoScrollRightBottom = () => {
- // clearInterval(scrollIntervalRightBottom);
- // scrollIntervalRightBottom = setInterval(() => {
- // if (currentZoomeRightBottom.end >= 100) {
- // currentZoomeRightBottom.start = 0;
- // currentZoomeRightBottom.end = 50;
- // } else {
- // currentZoomeRightBottom.start += 2;
- // currentZoomeRightBottom.end += 2;
- // }
- // chartOptionsRightBottom.value = {
- // ...chartOptionsRightBottom.value,
- // dataZoom: [
- // {
- // show: false,
- // type: 'slider',
- // yAxisIndex: 0,
- // start: currentZoomeRightBottom.start,
- // end: currentZoomeRightBottom.end,
- // },
- // ],
- // };
- // }, 2000);
- // };
- // onMounted(() => {
- // startAutoScrollRightTop();
- // startAutoScrollRightBottom();
- // });
- const mouseoverHandler = (e: any) => {
- console.log(e);
- };
- const clickHandler = (e: any) => {
- console.log(e);
- };
- // onUnmounted(() => {
- // clearInterval(scrollIntervalRightBottom);
- // clearInterval(scrollIntervalRightTop);
- // });
- </script>
- <style lang="less" scoped>
- :deep(*) {
- .el-descriptions__body {
- background-color: transparent;
- }
- .el-descriptions__label {
- color: #fff;
- }
- .el-descriptions__content {
- color: #ccc;
- }
- }
- .backgroundImages {
- background: url(@/assets/images/u1404.svg) center center no-repeat;
- }
- :deep(.left-bottom-board .dv-scroll-board .header) {
- height: 35px;
- }
- :deep(.left-bottom-board .dv-scroll-board .header-item) {
- font-size: 17px !important;
- color: #31e4cf !important;
- }
- :deep(.left-board .dv-scroll-board .header) {
- height: 30px !important;
- color: #31e4cf;
- }
- :deep(.left-board .row-item) {
- font-size: 17px;
- font-weight: 400;
- }
- :deep(.left-board .header-item) {
- font-weight: 400;
- font-size: 17px;
- }
- :deep(.center-board .dv-scroll-board .header) {
- height: 48px !important;
- color: #fff;
- font-size: 20px;
- font-weight: 700;
- }
- :deep(.left-bottom-board .dv-scroll-board .rows .ceil) {
- font-size: 17px;
- font-weight: 400;
- }
- :deep(.center-board .dv-scroll-board .rows .ceil) {
- font-size: 16px;
- color: rgba(247, 247, 247, 0.698039215686274);
- }
- :deep(.dv-scroll-ranking-board .ranking-info .rank) {
- width: auto !important;
- margin-right: 10px;
- }
- :deep(.dv-scroll-ranking-board .ranking-column) {
- height: 14px;
- border: none;
- background-color: rgba(232, 232, 232, 0.27843137254902);
- }
- :deep(.dv-scroll-ranking-board .ranking-column .inside-column) {
- height: 100%;
- background-color: rgba(115, 235, 233, 1);
- }
- </style>
|