|
|
<template>
|
|
|
<div class="app-container">
|
|
|
<div style="display: flex;justify-content: space-between;align-items: center;">
|
|
|
<span>当前登录人:{{user.name}}
|
|
|
</span>
|
|
|
|
|
|
<el-button type="primary">统计设置</el-button>
|
|
|
</div>
|
|
|
|
|
|
<el-row :gutter="20">
|
|
|
<el-col :span="16">
|
|
|
<el-card class="box-card" style="margin: 20px 0;">
|
|
|
<div slot="header" class="clearfix">
|
|
|
<span>预算总体进展情况</span>
|
|
|
<DatePicker :value="select.year" placeholder="选择所属年份" placement="bottom" style="width: 130px;float: right;"
|
|
|
type="year" @on-change="changeYear"></DatePicker>
|
|
|
</div>
|
|
|
<router-link :to="`/statisticalReport/budgetProgress`">
|
|
|
<div class="progress-card">
|
|
|
<div class="progress-card-item">
|
|
|
<div class="progress-card-item__num">
|
|
|
{{moneyFormat(statistic.progress ? statistic.progress.money_total_1 : 0)}}</div>
|
|
|
<div class="progress-card-item__label">年初预算合计金额</div>
|
|
|
</div>
|
|
|
<div class="progress-card-item">
|
|
|
<div class="progress-card-item__num">
|
|
|
{{moneyFormat(statistic.progress ? statistic.progress.money_total_2 : 0)}}</div>
|
|
|
<div class="progress-card-item__label">调整后预算合计金额</div>
|
|
|
</div>
|
|
|
<div class="progress-card-item">
|
|
|
<div class="progress-card-item__num">
|
|
|
{{moneyFormat(statistic.progress? statistic.progress.use_money_total : 0)}}</div>
|
|
|
<div class="progress-card-item__label">已支付金额</div>
|
|
|
</div>
|
|
|
<div class="progress-card-item">
|
|
|
<div class="progress-card-item__num">
|
|
|
{{toper(statistic.progress ? statistic.progress.money_total_1 : 0,statistic.progress ? statistic.progress.money_total_2 : 0,statistic.progress? statistic.progress.use_money_total : 0)}}%
|
|
|
</div>
|
|
|
<div class="progress-card-item__label">进展率</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</router-link>
|
|
|
</el-card>
|
|
|
|
|
|
<div ref="lxHeader">
|
|
|
<LxHeader icon="iconfont/icon--kucunguanli" text="待办事项" :custom="true" style="margin-bottom: 10px; border: 0px; margin-top: 15px">
|
|
|
<div slot="content" />
|
|
|
<slot>
|
|
|
<div></div>
|
|
|
</slot>
|
|
|
</LxHeader>
|
|
|
</div>
|
|
|
<div class="table-tree">
|
|
|
<el-table :data="list" border class="v-table" style="width: 100%;margin-bottom: 20px;">
|
|
|
<el-table-column type="index" label="序号" align="center" />
|
|
|
<el-table-column prop="type" width="100" label="类型" align="center" :formatter="typeFormatter" />
|
|
|
<el-table-column prop="content" label="内容" align="left" />
|
|
|
<el-table-column prop="created_at" width="200" label="下发时间" align="center" :formatter="timeFormatter" />
|
|
|
<el-table-column width="100" label="状态" align="center" prop="read_count">
|
|
|
<template slot-scope="{row, $index}">
|
|
|
<el-link v-if="row.read_count" type="success" :underline="false">已读</el-link>
|
|
|
<Button v-else type="error" size="small" style="margin-left: 10px;" ghost
|
|
|
@click="readIt(row, $index)">未读</Button>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column width="90" header-align="center" label="操作" align="center">
|
|
|
<template slot-scope="{row, $index}">
|
|
|
<Button type="primary" size="small" style="margin-left: 10px;" ghost @click="toContract(row)">查看</Button>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
|
|
|
<div style="display: flex;justify-content: flex-end;">
|
|
|
<Page :total="total" show-elevator @on-change="pageChange" />
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
|
<el-card class="box-card" style="margin: 20px 0;">
|
|
|
|
|
|
<div class="text item">
|
|
|
<pie-chart :chartData="rptChartData"></pie-chart>
|
|
|
</div>
|
|
|
|
|
|
</el-card>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
|
|
|
|
|
|
<div class="demo-split">
|
|
|
<Split v-model="split" style="height: 440px;">
|
|
|
<template #left>
|
|
|
<div class="demo-split-pane" style="padding-right: 5px;">
|
|
|
<div ref="lxHeader" v-if="statistic.departmentList">
|
|
|
<LxHeader icon="iconfont/icon--kucunguanli" text="科室进展情况" :custom="true" style="margin-bottom: 10px; border: 0px; margin-top: 15px">
|
|
|
<div slot="content" />
|
|
|
<slot>
|
|
|
<div style="width: 100%">
|
|
|
<xy-table :height="380" :list="statistic.departmentList" :table-item="departmentTable">
|
|
|
<template v-slot:btns>
|
|
|
<el-table-column :width="80" fixed="right" label="操作" header-align="center" align="center">
|
|
|
<template slot-scope="scope">
|
|
|
<router-link
|
|
|
:to="`/statisticalReport/budgetProgress?departmentId=${scope.row.plan_department_id}`">查看
|
|
|
</router-link>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</template>
|
|
|
</xy-table>
|
|
|
</div>
|
|
|
</slot>
|
|
|
</LxHeader>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
<template #right>
|
|
|
<div class="demo-split-pane" style="padding-left: 10px;">
|
|
|
<div ref="lxHeader" v-if="statistic.typeList">
|
|
|
<LxHeader icon="iconfont/icon--kucunguanli" text="预算类型进展情况" :custom="true" style="margin-bottom: 10px; border: 0px; margin-top: 15px">
|
|
|
<div slot="content" />
|
|
|
<slot>
|
|
|
<div style="width: 100%">
|
|
|
<xy-table :height="380" :list="statistic.typeList" :table-item="typeTable">
|
|
|
<template v-slot:btns>
|
|
|
<el-table-column :width="80" fixed="right" label="操作" header-align="center" align="center">
|
|
|
<template slot-scope="scope">
|
|
|
<router-link :to="`/statisticalReport/budgetProgress?typeId=${scope.row.type}`">查看
|
|
|
</router-link>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</template>
|
|
|
</xy-table>
|
|
|
</div>
|
|
|
</slot>
|
|
|
</LxHeader>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
</Split>
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<detailContract ref="detailContract"></detailContract>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import detailContract from "@/views/contract/components/detailContract"
|
|
|
import LxHeader from '@/components/LxHeader/index.vue'
|
|
|
import Pagination from '@/components/Pagination'
|
|
|
import PieChart from "./components/PieChart.vue"
|
|
|
import {
|
|
|
adminDepartmentList
|
|
|
} from '../../api/system/department.js'
|
|
|
import {
|
|
|
adminUserList,
|
|
|
getInfo
|
|
|
} from '../../api/user.js'
|
|
|
import {
|
|
|
getNotice,
|
|
|
readNotice,
|
|
|
statistic
|
|
|
} from "@/api/dashboard/notice"
|
|
|
import {
|
|
|
parseTime,
|
|
|
moneyFormatter
|
|
|
} from "@/utils/index"
|
|
|
import {
|
|
|
Message
|
|
|
} from "element-ui";
|
|
|
export default {
|
|
|
name: 'Manage',
|
|
|
components: {
|
|
|
LxHeader,
|
|
|
Pagination,
|
|
|
detailContract,
|
|
|
PieChart
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
value2: 12,
|
|
|
split: 0.5,
|
|
|
rptChartData: [],
|
|
|
select: {
|
|
|
year: ''
|
|
|
},
|
|
|
statistic: '',
|
|
|
department_id: [],
|
|
|
userIds: [],
|
|
|
list: [],
|
|
|
total: 0,
|
|
|
pageIndex: 1,
|
|
|
// listQuery: {
|
|
|
// page: 1,
|
|
|
// page_size: 10,
|
|
|
// show_self: 1,
|
|
|
// },
|
|
|
form: {
|
|
|
id: undefined,
|
|
|
},
|
|
|
dialogFormVisible: false,
|
|
|
departmentTree: [],
|
|
|
userList: [],
|
|
|
formLabelWidth: '200px',
|
|
|
user: {},
|
|
|
|
|
|
departmentProgress: [],
|
|
|
departmentTable: [{
|
|
|
label: '科室',
|
|
|
minWidth: 180,
|
|
|
prop: 'plan_department.name',
|
|
|
sortable: false,
|
|
|
align:"left",
|
|
|
fixed: "left"
|
|
|
},
|
|
|
{
|
|
|
label: '进展情况',
|
|
|
sortable: false,
|
|
|
minWidth: 220,
|
|
|
align: 'left',
|
|
|
fixed: "right",
|
|
|
customFn: (row) => {
|
|
|
let m2 = row?.money_total_2;
|
|
|
let m1 = row?.money_total_1;
|
|
|
let m3 = row?.use_money_total;
|
|
|
let per = 0;
|
|
|
|
|
|
if (m2 != 0) {
|
|
|
per = ((m3 / m2) * 100).toFixed(2);
|
|
|
} else if (m1 != 0) {
|
|
|
per = ((m3 / m1) * 100).toFixed(2);
|
|
|
}
|
|
|
return ( < div >
|
|
|
<el-progress percentage = {
|
|
|
Number(per)
|
|
|
}> </el-progress> </div >
|
|
|
)
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: '年初预算合计金额(元)',
|
|
|
width: 260,
|
|
|
align: 'right',
|
|
|
sortable: false,
|
|
|
prop: 'money_total_1',
|
|
|
formatter: (cell, data, value) => {
|
|
|
return moneyFormatter(value)
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: '调整后预算合计金额(元)',
|
|
|
width: 260,
|
|
|
align: 'right',
|
|
|
sortable: false,
|
|
|
prop: 'money_total_2',
|
|
|
formatter: (cell, data, value) => {
|
|
|
return moneyFormatter(value)
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: '已使用(元)',
|
|
|
width: 120,
|
|
|
align: 'right',
|
|
|
sortable: false,
|
|
|
prop: 'use_money_total',
|
|
|
formatter: (cell, data, value) => {
|
|
|
return moneyFormatter(value)
|
|
|
}
|
|
|
}
|
|
|
],
|
|
|
typeTable: [{
|
|
|
label: '预算类别',
|
|
|
width: 100,
|
|
|
prop: 'type_text',
|
|
|
sortable: false,
|
|
|
fixed: "left",
|
|
|
},
|
|
|
{
|
|
|
label: '进展情况',
|
|
|
sortable: false,
|
|
|
minWidth: 220,
|
|
|
align: 'left',
|
|
|
fixed: "right",
|
|
|
customFn: (row) => {
|
|
|
let m2 = row.money_total_2;
|
|
|
let m1 = row.money_total_1;
|
|
|
let m3 = row.use_money_total;
|
|
|
let per = 0;
|
|
|
|
|
|
if (m2 != 0) {
|
|
|
per = ((m3 / m2) * 100).toFixed(2);
|
|
|
} else if (m1 != 0) {
|
|
|
per = ((m3 / m1) * 100).toFixed(2);
|
|
|
}
|
|
|
return ( < div >
|
|
|
<el-progress percentage = {
|
|
|
Number(per)
|
|
|
}> </el-progress> </div >
|
|
|
)
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: '年初预算合计金额(元)',
|
|
|
width: 260,
|
|
|
align: 'right',
|
|
|
sortable: false,
|
|
|
prop: 'money_total_1',
|
|
|
formatter: (cell, data, value) => {
|
|
|
return moneyFormatter(value)
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: '调整后预算合计金额(元)',
|
|
|
width: 260,
|
|
|
align: 'right',
|
|
|
sortable: false,
|
|
|
prop: 'money_total_2',
|
|
|
formatter: (cell, data, value) => {
|
|
|
return moneyFormatter(value)
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
label: '已使用(元)',
|
|
|
width: 140,
|
|
|
align: 'right',
|
|
|
sortable: false,
|
|
|
prop: 'use_money_total',
|
|
|
formatter: (cell, data, value) => {
|
|
|
return moneyFormatter(value)
|
|
|
}
|
|
|
},
|
|
|
]
|
|
|
}
|
|
|
},
|
|
|
created() {
|
|
|
this.select.year = this.$moment().format('YYYY');
|
|
|
this.getNotices();
|
|
|
|
|
|
this.getStatistic();
|
|
|
|
|
|
getInfo().then(response => {
|
|
|
console.log(response)
|
|
|
this.user = response
|
|
|
}).catch(error => {})
|
|
|
},
|
|
|
methods: {
|
|
|
changeYear(e) {
|
|
|
this.select.year = e;
|
|
|
this.getStatistic()
|
|
|
|
|
|
},
|
|
|
async getStatistic() {
|
|
|
const res = await statistic(this.select)
|
|
|
console.log(res)
|
|
|
this.statistic = res;
|
|
|
|
|
|
this.rptChartData = {
|
|
|
xArr: ["预算合计金额","预算已执行金额"],
|
|
|
radiusArr: '50%',
|
|
|
yArr: [{ value: res.progress.money_total_1, name: '预算合计金额',
|
|
|
label:{
|
|
|
show:false//这个数据高亮时不显示label,就不会显示替遮住第一个数据的label值了
|
|
|
},
|
|
|
emphasis:{
|
|
|
label:{
|
|
|
show:false//这个数据高亮时不显示label,就不会显示替遮住第一个数据的label值了
|
|
|
}
|
|
|
} },
|
|
|
{ value: res.progress.use_money_total, name: '预算已执行金额' }]
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
toContract(row) {
|
|
|
this.$refs['detailContract'].getDetail(row.contract_id)
|
|
|
this.$refs['detailContract'].isShowDetail = true
|
|
|
},
|
|
|
|
|
|
pageChange(e) {
|
|
|
this.pageIndex = e
|
|
|
this.getNotices()
|
|
|
},
|
|
|
|
|
|
timeFormatter(cell, data, value) {
|
|
|
return parseTime(new Date(value))
|
|
|
},
|
|
|
typeFormatter(cell, data, value) {
|
|
|
return value === 1 ? '合同流程' : '付款计划'
|
|
|
},
|
|
|
toper(m1, m2, m3) {
|
|
|
if (m2 != 0) {
|
|
|
return ((m3 / m2) * 100).toFixed(2);
|
|
|
} else if (m1 != 0) {
|
|
|
return ((m3 / m1) * 100).toFixed(2);
|
|
|
} else
|
|
|
return 0
|
|
|
},
|
|
|
async getNotices() {
|
|
|
const res = await getNotice({
|
|
|
page_size: 10,
|
|
|
page: this.pageIndex
|
|
|
})
|
|
|
this.list = res.data
|
|
|
this.total = res.total
|
|
|
},
|
|
|
|
|
|
|
|
|
filterChildren(data) {
|
|
|
data.forEach(i => {
|
|
|
if (i.children && i.children.length > 0) {
|
|
|
this.filterChildren(i.children)
|
|
|
} else {
|
|
|
delete i.children
|
|
|
}
|
|
|
})
|
|
|
},
|
|
|
getList() {
|
|
|
index(this.listQuery).then(response => {
|
|
|
this.list = response.data
|
|
|
this.total = response.total
|
|
|
}).catch(error => {})
|
|
|
},
|
|
|
handleFilter() {
|
|
|
this.listQuery.page = 1
|
|
|
this.getList()
|
|
|
},
|
|
|
readIt(row) {
|
|
|
readNotice({
|
|
|
id: row.id
|
|
|
}).then(res => {
|
|
|
Message({
|
|
|
type: 'success',
|
|
|
message: '已读'
|
|
|
})
|
|
|
this.getNotices()
|
|
|
})
|
|
|
// show({id: row.id}).then(r => { this.form = r }).catch(error => {})
|
|
|
// this.list[index].is_read = 1
|
|
|
},
|
|
|
save() {
|
|
|
this.$refs['dataForm'].validate((valid) => {
|
|
|
if (valid) {
|
|
|
const tempData = Object.assign({}, this.form)
|
|
|
tempData.admin_id_list = tempData.ids.map(i => {
|
|
|
return {
|
|
|
admin_id: i
|
|
|
}
|
|
|
})
|
|
|
if (tempData.id) {
|
|
|
save(tempData).then(r => {
|
|
|
this.saved()
|
|
|
}).catch(error => {})
|
|
|
} else {
|
|
|
store(tempData).then(r => {
|
|
|
this.saved()
|
|
|
}).catch(error => {})
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
},
|
|
|
saved() {
|
|
|
this.handleFilter()
|
|
|
this.dialogFormVisible = false
|
|
|
this.$message.success('保存成功')
|
|
|
},
|
|
|
handleDelete(row, index) {
|
|
|
this.$confirm('确定要删除吗?', '提示', {
|
|
|
confirmButtonText: '确定',
|
|
|
cancelButtonText: '取消',
|
|
|
type: 'warning'
|
|
|
}).then(() => {
|
|
|
destroy({
|
|
|
id: row.id
|
|
|
}).then(response => {
|
|
|
this.$message.success('删除成功')
|
|
|
this.getList()
|
|
|
}).catch(error => {})
|
|
|
}).catch(() => {});
|
|
|
},
|
|
|
},
|
|
|
computed: {
|
|
|
moneyFormat() {
|
|
|
return function(price) {
|
|
|
return moneyFormatter(price)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
<style scoped lang="scss">
|
|
|
::v-deep .el-dialog__body {
|
|
|
padding: 8px 20px;
|
|
|
}
|
|
|
|
|
|
::v-deep .el-col-5 {
|
|
|
width: 20%;
|
|
|
}
|
|
|
|
|
|
::v-deep .el-card__body {
|
|
|
padding: 4px 10px !important;
|
|
|
}
|
|
|
|
|
|
.progress-card {
|
|
|
display: flex;
|
|
|
|
|
|
&-item {
|
|
|
text-align: center;
|
|
|
flex: 1;
|
|
|
|
|
|
&__label {
|
|
|
font-size: 14px;
|
|
|
}
|
|
|
|
|
|
&__num {
|
|
|
font-size: 20px;
|
|
|
font-weight: 600;
|
|
|
|
|
|
padding: 6px 0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
</style>
|
|
|
<style lang="scss" scoped>
|
|
|
.ivu-btn {
|
|
|
margin-right: 10px;
|
|
|
}
|
|
|
|
|
|
.table-tree {
|
|
|
margin-top: 10px;
|
|
|
}
|
|
|
|
|
|
.v-text {
|
|
|
padding: 8px 0;
|
|
|
border-bottom: 1px solid #eee;
|
|
|
margin-bottom: 20px;
|
|
|
|
|
|
.title {
|
|
|
color: #338de3;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.dataGroup {
|
|
|
padding: 10px 0;
|
|
|
}
|
|
|
|
|
|
.grid-content {
|
|
|
border-radius: 5px;
|
|
|
text-align: center;
|
|
|
background: #ffffff;
|
|
|
padding: 15px 0;
|
|
|
|
|
|
p {
|
|
|
line-height: 1.8;
|
|
|
}
|
|
|
|
|
|
p:first-child {
|
|
|
font-weight: 700;
|
|
|
font-size: 16px;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.bg-org {
|
|
|
border: 2px solid #EF6C24;
|
|
|
color: #EF6C24;
|
|
|
}
|
|
|
|
|
|
.bg-blue {
|
|
|
border: 2px solid #0800FF;
|
|
|
color: #0800FF;
|
|
|
}
|
|
|
|
|
|
.bg-green {
|
|
|
border: 2px solid #0F9700;
|
|
|
color: #0F9700;
|
|
|
}
|
|
|
|
|
|
.bg-black {
|
|
|
border: 2px solid #333;
|
|
|
color: #333;
|
|
|
}
|
|
|
|
|
|
.bg-pink {
|
|
|
border: 2px solid #FF0000;
|
|
|
color: #FF0000;
|
|
|
}
|
|
|
</style>
|