9 changed files with 548 additions and 40 deletions
@ -0,0 +1,90 @@ |
|||
<template> |
|||
<v-chart :option="option" theme="auto" :autoresize="true" style="width: 100%; height: 200px" /> |
|||
</template> |
|||
|
|||
<script lang="ts" name="DonutChart" setup> |
|||
import { ref, reactive } from 'vue' |
|||
let receivingParameter = defineProps(["fininshNum", "unfininshNum", "name"]) |
|||
let option = reactive({}) |
|||
option = { |
|||
tooltip: { |
|||
trigger: 'item', |
|||
formatter: '{a} <br/>{b}: {c} ({d}%)' |
|||
}, |
|||
legend: { |
|||
// data: [ |
|||
// '已完成', |
|||
// '未完成' |
|||
// ], |
|||
left: 'left', |
|||
// orient: 'vertical', |
|||
}, |
|||
series: [ |
|||
// { |
|||
// name: 'Access From', |
|||
// type: 'pie', |
|||
// selectedMode: 'single', |
|||
// radius: [0, '30%'], |
|||
// label: { |
|||
// position: 'inner', |
|||
// fontSize: 14 |
|||
// }, |
|||
// labelLine: { |
|||
// show: false |
|||
// }, |
|||
// }, |
|||
{ |
|||
name: receivingParameter.name, |
|||
type: 'pie', |
|||
radius: ['30%', '60%'], |
|||
labelLine: { |
|||
length: 10 |
|||
}, |
|||
label: { |
|||
// formatter: '{a|{a}}{abg|}\n{hr|}\n {b|{b}:}{c} {per|{d}%} ', |
|||
formatter: ' {b|{b}:}{per|{d}%} \n{hr|}\n{c|{c}}',//d是百分比,c是数值,b是名称,a是name |
|||
|
|||
backgroundColor: '#F6F8FC', |
|||
borderColor: '#8C8D8E', |
|||
borderWidth: 1, |
|||
borderRadius: 4, |
|||
rich: { |
|||
a: { |
|||
color: '#6E7079', |
|||
lineHeight: 22, |
|||
align: 'center' |
|||
}, |
|||
hr: { |
|||
borderColor: '#8C8D8E', |
|||
width: '100%', |
|||
borderWidth: 1, |
|||
height: 0 |
|||
}, |
|||
b: { |
|||
color: '#4C5058', |
|||
fontSize: 14, |
|||
// fontWeight: 'bold', |
|||
// lineHeight: 33 |
|||
}, |
|||
per: { |
|||
color: '#fff', |
|||
backgroundColor: '#4C5058', |
|||
padding: [3, 4], |
|||
borderRadius: 4 |
|||
}, |
|||
c: { |
|||
align: 'center' // 样式c居中对齐 |
|||
} |
|||
} |
|||
}, |
|||
data: [ |
|||
{ value: receivingParameter.fininshNum, name: '已完成', itemStyle: { color: '#00A2E8', } },//天蓝色 |
|||
{ value: receivingParameter.unfininshNum, name: '未完成', itemStyle: { color: '#DCE0E6', } }, |
|||
], |
|||
} |
|||
] |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style></style> |
@ -0,0 +1,68 @@ |
|||
<template> |
|||
<v-chart :option="option" theme="auto" :autoresize="true" style="width: 100%; height: 200px" /> |
|||
</template> |
|||
|
|||
<script lang="ts" name="DonutChart" setup> |
|||
import { ref, reactive } from 'vue' |
|||
let receivingParameter = defineProps(["fininshNum", "unfininshNum", "name"]) |
|||
let option = reactive({}) |
|||
option = { |
|||
tooltip: { |
|||
trigger: 'item', |
|||
formatter: '{a} <br/>{b}: {c} ({d}%)' |
|||
}, |
|||
legend: { |
|||
// data: [ |
|||
// '已完成', |
|||
// '未完成' |
|||
// ], |
|||
left: 'left', |
|||
// orient: 'vertical', |
|||
}, |
|||
series: [ |
|||
// { |
|||
// name: 'Access From', |
|||
// type: 'pie', |
|||
// selectedMode: 'single', |
|||
// radius: [0, '30%'], |
|||
// label: { |
|||
// position: 'inner', |
|||
// fontSize: 14 |
|||
// }, |
|||
// labelLine: { |
|||
// show: false |
|||
// }, |
|||
// }, |
|||
{ |
|||
name: receivingParameter.name, |
|||
type: 'pie', |
|||
radius: ['50%', '80%'], |
|||
label: { |
|||
alignTo: 'edge', |
|||
formatter: '{name|{b}}\n{time|{c}元}\n{value|{d}%}', |
|||
minMargin: 5, |
|||
edgeDistance: 10, |
|||
lineHeight: 15, |
|||
rich: { |
|||
time: { |
|||
fontSize: 10, |
|||
color: '#999' |
|||
} |
|||
} |
|||
}, |
|||
labelLine: { |
|||
length: 10, |
|||
length2: 0, |
|||
maxSurfaceAngle: 80 |
|||
}, |
|||
data: [ |
|||
{ value: receivingParameter.fininshNum, name: '已支付', itemStyle: { color: '#53E3CC', } }, |
|||
{ value: receivingParameter.unfininshNum, name: '未支付', itemStyle: { color: '#CC0033 ', } }, |
|||
], |
|||
} |
|||
] |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style></style> |
@ -0,0 +1,51 @@ |
|||
<template> |
|||
<v-chart :option="option" theme="auto" :autoresize="true" style="width: 100%; height: 200px" /> |
|||
</template> |
|||
|
|||
<script lang="ts" name="PieChart" setup> |
|||
import { ref, reactive } from 'vue' |
|||
let receivingParameter = defineProps(["data"]) |
|||
let option = reactive({}) |
|||
option = { |
|||
tooltip: { |
|||
trigger: 'item' |
|||
}, |
|||
legend: { |
|||
left: 'left', |
|||
orient: 'vertical', |
|||
}, |
|||
series: [ |
|||
{ |
|||
name: '项目状态', |
|||
type: 'pie', |
|||
radius: '90%', |
|||
data: receivingParameter.data, |
|||
// data: [ |
|||
// { value: 1048, name: '待入库' }, |
|||
// { value: 735, name: '入库中' }, |
|||
// { value: 580, name: '已入库' }, |
|||
// { value: 484, name: '计划审批中' }, |
|||
// { value: 300, name: '计划执行中' }, |
|||
// { value: 300, name: '已归档' }, |
|||
// { value: 1, name: '已出库' } |
|||
|
|||
|
|||
// ], |
|||
label: { |
|||
show: false, |
|||
position: 'center' |
|||
}, |
|||
// emphasis: { |
|||
// itemStyle: { |
|||
// shadowBlur: 10, |
|||
// shadowOffsetX: 0, |
|||
// shadowColor: 'rgba(0, 0, 0, 0.5)' |
|||
// } |
|||
// } |
|||
} |
|||
] |
|||
}; |
|||
|
|||
</script> |
|||
|
|||
<style></style> |
@ -1,38 +1,145 @@ |
|||
<template> |
|||
<PageWrapper> |
|||
<template #headerContent> <WorkbenchHeader /> </template> |
|||
<div class="lg:flex"> |
|||
<div class="lg:w-7/10 w-full !mr-4 enter-y"> |
|||
<template #headerContent> |
|||
<WorkbenchHeader /> |
|||
</template> |
|||
<div > |
|||
<ProjectCard :loading="loading" class="enter-y" /> |
|||
<!-- <DynamicInfo :loading="loading" class="!my-4 enter-y" /> --> |
|||
</div> |
|||
<div class="lg:w-3/10 w-full enter-y"> |
|||
<!-- <QuickNav :loading="loading" class="enter-y" /> --> |
|||
|
|||
<Card class="!my-4 enter-y" :loading="loading"> |
|||
<img class="xl:h-50 h-30 mx-auto" src="../../../assets/svg/illustration.svg" /> |
|||
</Card> |
|||
|
|||
<!-- <SaleRadar :loading="loading" class="enter-y" /> --> |
|||
</div> |
|||
<div class="card-container"> |
|||
<a-tabs v-model:activeKey="activeKey" type="card"> |
|||
<a-tab-pane key="1" tab="总进度"> |
|||
<div style="background-color: #ececec; padding: 20px"> |
|||
<a-row :gutter="16"> |
|||
<a-col :span="8"> |
|||
<a-card title="项目总进度" :bordered="false"> |
|||
<!-- <el-progress type="circle" :percentage="25" :stroke-width="10" /> --> |
|||
<DonutChart :fininshNum="data.xiangmZJD.fininshNum" :unfininshNum="data.xiangmZJD.unfininshNum" |
|||
:name="'项目总进度'" /> |
|||
</a-card> |
|||
</a-col> |
|||
<a-col :span="8"> |
|||
<a-card title="资金支付情况" :bordered="false"> |
|||
<DonutChartByMoney :fininshNum="data.xiangmuZJ.fininshNum" :unfininshNum="data.xiangmuZJ.unfininshNum" |
|||
:name="'资金支付情况'" /> |
|||
</a-card> |
|||
</a-col> |
|||
<a-col :span="8"> |
|||
<a-card title="项目状态" :bordered="false"> |
|||
<PieChart :data="data.xiangmuZT" /> |
|||
</a-card> |
|||
</a-col> |
|||
</a-row> |
|||
</div> |
|||
<div> |
|||
<planSummary /> |
|||
</div> |
|||
</a-tab-pane> |
|||
<a-tab-pane key="2" tab="所属改革任务"> |
|||
<div style="background-color: #ececec; padding: 20px"> |
|||
<a-row :gutter="16"> |
|||
<a-col :span="8" v-for="(item, index) in data.SSGGRW" :key="index"> |
|||
<a-card :title="item.name" :bordered="false"> |
|||
<!-- <el-progress type="circle" :percentage="25" :stroke-width="10" /> --> |
|||
<DonutChart :fininshNum="item.fininshNum" :unfininshNum="item.unfininshNum" :name="item.name" /> |
|||
</a-card> |
|||
</a-col> |
|||
</a-row> |
|||
</div> |
|||
</a-tab-pane> |
|||
<a-tab-pane key="3" tab="行政区域"> |
|||
<div style="background-color: #ececec; padding: 20px"> |
|||
<a-row :gutter="16"> |
|||
<a-col :span="8" v-for="(item, index) in data.XXQY" :key="index"> |
|||
<a-card :title="item.name" :bordered="false"> |
|||
<!-- <el-progress type="circle" :percentage="25" :stroke-width="10" /> --> |
|||
<DonutChart :fininshNum="item.fininshNum" :unfininshNum="item.unfininshNum" :name="item.name" /> |
|||
</a-card> |
|||
</a-col> |
|||
</a-row> |
|||
</div> |
|||
</a-tab-pane> |
|||
<a-tab-pane key="4" tab="单位属性"> |
|||
<div style="background-color: #ececec; padding: 20px"> |
|||
<a-row :gutter="16"> |
|||
<a-col :span="8" v-for="(item, index) in data.DWSX" :key="index"> |
|||
<a-card :title="item.name" :bordered="false"> |
|||
<!-- <el-progress type="circle" :percentage="25" :stroke-width="10" /> --> |
|||
<DonutChart :fininshNum="item.fininshNum" :unfininshNum="item.unfininshNum" :name="item.name" /> |
|||
</a-card> |
|||
</a-col> |
|||
</a-row> |
|||
</div> |
|||
</a-tab-pane> |
|||
</a-tabs> |
|||
</div> |
|||
<div> |
|||
<planSummary/> |
|||
</div> |
|||
</PageWrapper> |
|||
</template> |
|||
<script lang="ts" setup> |
|||
import { ref } from 'vue'; |
|||
import { Card } from 'ant-design-vue'; |
|||
import { PageWrapper } from '@/components/Page'; |
|||
import WorkbenchHeader from './components/WorkbenchHeader.vue'; |
|||
import ProjectCard from './components/ProjectCard.vue'; |
|||
import QuickNav from './components/QuickNav.vue'; |
|||
import DynamicInfo from './components/DynamicInfo.vue'; |
|||
import SaleRadar from './components/SaleRadar.vue'; |
|||
import planSummary from '@/views/projectSummary/planSummary/index.vue'; |
|||
const loading = ref(true); |
|||
setTimeout(() => { |
|||
loading.value = false; |
|||
}, 1500); |
|||
import { ref, reactive } from 'vue'; |
|||
import { PageWrapper } from '@/components/Page'; |
|||
import WorkbenchHeader from './components/WorkbenchHeader.vue'; |
|||
import DonutChart from './components/DonutChart.vue'; |
|||
import PieChart from './components/PieChart.vue'; |
|||
import ProjectCard from './components/ProjectCard.vue'; |
|||
|
|||
import DonutChartByMoney from './components/DonutChartByMoney.vue'; |
|||
import planSummary from '@/views/projectSummary/planSummary/indeForDashboard.vue'; |
|||
const loading = ref(true); |
|||
const activeKey = ref('1'); |
|||
const data = reactive({ |
|||
xiangmZJD: { |
|||
fininshNum: 40, |
|||
unfininshNum: 10, |
|||
}, |
|||
xiangmuZJ: { |
|||
fininshNum: 400000, |
|||
unfininshNum: 230000, |
|||
}, |
|||
xiangmuZT: [ |
|||
{ value: 1048, name: '待入库' }, |
|||
{ value: 735, name: '入库中' }, |
|||
{ value: 580, name: '已入库' }, |
|||
{ value: 484, name: '计划审批中' }, |
|||
{ value: 300, name: '计划执行中' }, |
|||
{ value: 300, name: '已归档' }, |
|||
{ value: 12, name: '已出库' } |
|||
], |
|||
SSGGRW: [ |
|||
{ name: "2+N紧密型城市医疗集团建设", fininshNum: 100, unfininshNum: 30 }, |
|||
{ name: "2+9+9+N县域医共体建设", fininshNum: 140, unfininshNum: 20 }, |
|||
{ name: "市县公立医院妇幼能力建设", fininshNum: 140, unfininshNum: 120 }, |
|||
{ name: "高水平县级医院建设 ", fininshNum: 140, unfininshNum: 90 }, |
|||
{ name: "打造长三角市域医学高地", fininshNum: 140, unfininshNum: 90 }, |
|||
{ name: "公立医院院前急救与院内救治服务融合发展", fininshNum: 170, unfininshNum: 90 }, |
|||
{ name: "医共体下三医联动改革", fininshNum: 170, unfininshNum: 90 }, |
|||
{ name: "智慧医院服务能力提档升级", fininshNum: 100, unfininshNum: 30 }, |
|||
{ name: "数字健康大脑建设", fininshNum: 140, unfininshNum: 270 }, |
|||
{ name: "舒心就医", fininshNum: 140, unfininshNum: 270 }, |
|||
{ name: "中医药固本培元", fininshNum: 140, unfininshNum: 210 }, |
|||
{ name: "公立医院运营管理", fininshNum: 140, unfininshNum: 80 }, |
|||
{ name: "公立医院党建全行业引领改革工程 ", fininshNum: 140, unfininshNum: 40 }, |
|||
{ name: "高质量临床重点专科建设 ", fininshNum: 140, unfininshNum: 80 }, |
|||
], |
|||
XXQY: [ |
|||
{ name: "南浔区", fininshNum: 100, unfininshNum: 30 }, |
|||
{ name: "吴兴区", fininshNum: 140, unfininshNum: 20 }, |
|||
{ name: "市本级", fininshNum: 140, unfininshNum: 120 }, |
|||
{ name: "安吉县", fininshNum: 140, unfininshNum: 90 }, |
|||
{ name: "德清县", fininshNum: 140, unfininshNum: 90 }, |
|||
{ name: "长兴县", fininshNum: 170, unfininshNum: 90 }, |
|||
], |
|||
DWSX: [ |
|||
{ name: "卫生行政部门", fininshNum: 1000, unfininshNum: 3000 }, |
|||
{ name: "医疗机构 ", fininshNum: 1400, unfininshNum: 2000 }, |
|||
|
|||
] |
|||
|
|||
|
|||
}) |
|||
|
|||
setTimeout(() => { |
|||
loading.value = false; |
|||
}, 1500); |
|||
</script> |
|||
|
@ -0,0 +1,193 @@ |
|||
<template> |
|||
<PageWrapper dense> |
|||
<!--引用表格--> |
|||
<BasicTable @register="registerTable"> |
|||
|
|||
<template v-for="(item, index) in planSummary" v-slot:[item.dataIndex]="{ record }"> |
|||
<div v-if="record[item.dataIndex]"> |
|||
<span>{{ record[item.dataIndex].taskName }}</span> |
|||
<Progress type="circle" :percent="record[item.dataIndex].percent" :size="20" :strokeColor="record[item.dataIndex].color" @click="handleViewPlanDetail(record[item.dataIndex].id, record[item.dataIndex].color)"></Progress> |
|||
</div> |
|||
</template> |
|||
<!-- <template #phaseNumber0="{ record }"> |
|||
<div v-if="record.phaseNumber0"> |
|||
<span>{{ record.phaseNumber0.taskName }}</span> |
|||
<Progress type="circle" :percent="record.phaseNumber0.percent" :size="20" :strokeColor="record.phaseNumber0.color"></Progress> |
|||
</div> |
|||
</template> |
|||
<template #phaseNumber1="{ record }"> |
|||
<div v-if="record.phaseNumber1"> |
|||
<span>{{ record.phaseNumber1.taskName }}</span> |
|||
<Progress type="circle" :percent="record.phaseNumber1.percent" :size="20" :strokeColor="record.phaseNumber1.color" ></Progress> |
|||
</div> |
|||
</template> |
|||
<template #phaseNumber2="{ record }"> |
|||
<div v-if="record.phaseNumber2"> |
|||
<span>{{ record.phaseNumber2.taskName }}</span> |
|||
<Progress type="circle" :percent="record.phaseNumber2.percent" :size="20" :strokeColor="record.phaseNumber2.color" ></Progress> |
|||
</div> |
|||
</template> |
|||
<template #phaseNumber3="{ record }"> |
|||
<div v-if="record.phaseNumber3"> |
|||
<span>{{ record.phaseNumber3.taskName }}</span> |
|||
<Progress type="circle" :percent="record.phaseNumber3.percent" :size="20" :strokeColor="record.phaseNumber3.color" ></Progress> |
|||
</div> |
|||
|
|||
|
|||
</template> |
|||
<template #phaseNumber4="{ record }"> |
|||
<div v-if="record.phaseNumber4"> |
|||
<span>{{ record.phaseNumber4.taskName }}</span> |
|||
<Progress type="circle" :percent="record.phaseNumber4.percent" :size="20" :strokeColor="record.phaseNumber4.color" ></Progress> |
|||
</div> |
|||
</template> |
|||
<template #phaseNumber5="{ record }"> |
|||
<div v-if="record.phaseNumber5"> |
|||
<span>{{ record.phaseNumber5.taskName }}</span> |
|||
<Progress type="circle" :percent="record.phaseNumber5.percent" :size="20" :strokeColor="record.phaseNumber5.color" ></Progress> |
|||
</div> |
|||
</template> |
|||
<template #phaseNumber6="{ record }"> |
|||
<div v-if="record.phaseNumber6"> |
|||
<span>{{ record.phaseNumber6.taskName }}</span> |
|||
<Progress type="circle" :percent="record.phaseNumber6.percent" :size="20" :strokeColor="record.phaseNumber6.color" ></Progress> |
|||
</div> |
|||
</template> --> |
|||
|
|||
</BasicTable> |
|||
<!-- <BasicModal @register="registeViewPlanDetail" title="项目计划详情" width="1200px" :showOkBtn="false"> |
|||
<viewPlanDetail :projectId="projectId" :projectStage="projectStage" /> |
|||
</BasicModal> |
|||
<BasicModal @register="registerProjectPlan" title="发起项目计划审批" width="1200px" :showOkBtn="false" |
|||
:showCancelBtn="false"> |
|||
<addPlan :type="type" :projectid="projectId" @close="closeProjectPlanModal()" /> |
|||
</BasicModal> --> |
|||
</PageWrapper> |
|||
|
|||
</template> |
|||
|
|||
<script lang="ts" name="indeForDashboard" setup> |
|||
//ts语法 |
|||
import { ref, onMounted } from 'vue'; |
|||
import { BasicTable, useTable } from '@/components/Table'; |
|||
import { PageWrapper } from '@/components/Page'; |
|||
import { Progress } from 'ant-design-vue'; |
|||
|
|||
import { searchFormSchema } from '@/views/projectLib/projectInfo/projectInfo.data'; |
|||
import { planSummaryColumn } from '@/views/projectSummary/planSummary/planSummary.data'; |
|||
import { getplanSummary } from '@/views/projectSummary/planSummary/planSummary.api' |
|||
|
|||
onMounted(async () => { |
|||
|
|||
}) |
|||
let planSummary = ref<Array<any>>([]); |
|||
|
|||
const [registerTable, { setColumns }] = useTable({ |
|||
api: getplanSummary, |
|||
columns: planSummaryColumn, |
|||
rowKey:"projectName", |
|||
showIndexColumn:false, |
|||
useSearchForm: false, |
|||
// actionColumn: { |
|||
// width: 140, |
|||
// title: '操作', |
|||
// dataIndex: 'action', |
|||
// slots: { customRender: 'action' }, |
|||
// }, |
|||
afterFetch: (data) => { |
|||
planSummary.value.pop() |
|||
let temp = JSON.parse(JSON.stringify(planSummaryColumn)) |
|||
data.forEach(item => { |
|||
Object.entries(item).forEach(([key, value]) => { |
|||
if (key.includes("phaseNumber")) { |
|||
let keyExists = true; |
|||
Object.entries(temp).forEach(([keytemp, valuetemp]) => { |
|||
if (valuetemp.dataIndex == key) { |
|||
keyExists = false |
|||
return |
|||
} |
|||
}) |
|||
if (keyExists) { |
|||
temp.push({ |
|||
title: key.replace("phaseNumber", "阶段"), |
|||
dataIndex: key, |
|||
slots: { customRender: key }, |
|||
align:'left' |
|||
}) |
|||
planSummary.value.push({ |
|||
title: key, |
|||
dataIndex: key, |
|||
}) |
|||
} |
|||
} |
|||
|
|||
}); |
|||
}) |
|||
console.log("lanSummary.valu", planSummary.value); |
|||
setColumns(temp) |
|||
}, |
|||
//表单查询项设置 |
|||
formConfig: { |
|||
schemas: searchFormSchema, |
|||
} |
|||
|
|||
}); |
|||
function handleViewPlanDetail(projectId: string, color: string) { |
|||
console.log("handleViewPlanDetail", projectId, color); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
</script> |
|||
|
|||
<style scoped> |
|||
.timeline { |
|||
display: flex; |
|||
width: 100%; |
|||
margin-bottom: 100px; |
|||
|
|||
.lineitem { |
|||
transform: translateX(50%); |
|||
width: 25%; |
|||
} |
|||
} |
|||
|
|||
::v-deep .el-timeline-item__tail { |
|||
border-left: none; |
|||
width: 100%; |
|||
border-top: 2px solid #e4e7ed; |
|||
position: absolute; |
|||
top: 6px; |
|||
} |
|||
|
|||
::v-deep .el-timeline-item__wrapper { |
|||
padding-left: 0; |
|||
position: absolute; |
|||
top: 20px; |
|||
transform: translateX(-50%); |
|||
text-align: center; |
|||
} |
|||
|
|||
::v-deep .el-timeline-item__timestamp { |
|||
font-size: 14px; |
|||
} |
|||
|
|||
.nested-timeline { |
|||
margin-left: 20px; |
|||
border-left: 1px dashed #ccc; |
|||
padding-left: 20px; |
|||
} |
|||
|
|||
.nested-timeline-item { |
|||
margin-bottom: 10px; |
|||
} |
|||
|
|||
|
|||
::v-deep .ant-table-expanded-row { |
|||
height: auto !important; |
|||
/* 其他样式 */ |
|||
} |
|||
</style> |
Loading…
Reference in new issue