lynn 3 months ago
commit 464cb4a243

@ -19,7 +19,7 @@ export default {
watch: { watch: {
$route(to, from) { $route(to, from) {
const locationHash = window.location.hash const locationHash = window.location.hash
console.log("locationHash",locationHash)
this.$matomo.setCustomUrl(locationHash.replace(/#/g, '')) this.$matomo.setCustomUrl(locationHash.replace(/#/g, ''))
this.$matomo.trackPageView(to.meta.title) // this.$matomo.trackPageView(to.meta.title) //
} }

@ -1,195 +1,167 @@
<template> <template>
<div :class="className" :style="{ height: height, width: width }" ref="chartContainer" /> <div :class="className" :style="{ height: height, width: width }" ref="chartContainer" />
</template> </template>
<script> <script>
import * as echarts from 'echarts' import * as echarts from 'echarts'
import resize from '@/mixins/resize' import resize from '@/mixins/resize'
export default { export default {
mixins: [resize], mixins: [resize],
props: { props: {
className: { className: {
type: String, type: String,
default: '' default: ''
}, },
height: { height: {
type: String, type: String,
default: '350px' // default: '350px' //
},
width: {
type: String,
default: '300px'
},
chartData: {
type: Array,
required: true
},
title: {
type: String,
default: '数据统计'
}
}, },
width: { data() {
type: String, return {
default: '300px' chart: null,
showRemaining: false,
usedAmount: 0,
totalAmount: 0,
remainingAmount: 0,
usedPercent: 0
}
}, },
chartData: { computed: {
type: Array, formattedUsedAmount() {
required: true return this.usedAmount.toFixed(2)
},
formattedRemainingAmount() {
return this.remainingAmount.toFixed(2)
},
formattedUsedPercent() {
return this.usedPercent.toFixed(2)
},
formattedRemainingPercent() {
return (100 - this.usedPercent).toFixed(2)
}
}, },
title: { mounted() {
type: String, this.$nextTick(() => {
default: '数据统计' this.initChart()
} // this.bindEvents()
}, })
data() {
return {
chart: null,
showRemaining: false,
usedAmount: 0,
totalAmount: 0,
remainingAmount: 0,
usedPercent: 0
}
},
computed: {
formattedUsedAmount() {
return this.usedAmount.toFixed(2)
}, },
formattedRemainingAmount() { beforeDestroy() {
return this.remainingAmount.toFixed(2) if (this.chart) {
this.chart.dispose()
}
}, },
formattedUsedPercent() { watch: {
return this.usedPercent.toFixed(2) chartData: {
handler() {
this.setOptions()
},
deep: true
}
}, },
formattedRemainingPercent() { methods: {
return (100 - this.usedPercent).toFixed(2) initChart() {
} this.chart = echarts.init(this.$refs.chartContainer)
},
mounted() {
this.$nextTick(() => {
this.initChart()
this.bindEvents()
})
},
beforeDestroy() {
if (this.chart) {
this.chart.dispose()
}
},
watch: {
chartData: {
handler() {
this.setOptions() this.setOptions()
}, },
deep: true setOptions() {
} // chartData
}, const usedItem = this.chartData.find(item => item.name === '已用金额') || { value: 0 }
methods: { const totalItem = this.chartData.find(item => item.name === '合计金额') || { value: 0 }
initChart() {
this.chart = echarts.init(this.$refs.chartContainer)
this.setOptions()
},
setOptions() {
// chartData
const usedItem = this.chartData.find(item => item.name === '已用金额') || { value: 0 }
const totalItem = this.chartData.find(item => item.name === '合计金额') || { value: 0 }
this.usedAmount = parseFloat(usedItem.value) || 0 this.usedAmount = parseFloat(usedItem.value) || 0
this.totalAmount = parseFloat(totalItem.value) || 0 this.totalAmount = parseFloat(totalItem.value) || 0
this.remainingAmount = Math.max(0, this.totalAmount - this.usedAmount) this.remainingAmount = Math.max(0, this.totalAmount - this.usedAmount)
this.usedPercent = this.totalAmount > 0 this.usedPercent = this.totalAmount > 0
? (this.usedAmount / this.totalAmount) * 100 ? (this.usedAmount / this.totalAmount) * 100
: 0 : 0
const option = { const option = {
// //
legend: { legend: {
type: 'plain', type: 'plain',
orient: 'horizontal', // orient: 'horizontal', //
bottom: 0, // bottom: 0, //
left: 'center', // left: 'center', //
itemWidth: 12, // itemWidth: 12, //
itemHeight: 12, // itemHeight: 12, //
textStyle: { textStyle: {
fontSize: 10, fontSize: 10,
color: '#333' color: '#333'
}, },
data: [ data: [
{ name: '已用金额', icon: 'circle' }, { name: '已用金额', icon: 'circle' },
{ name: '剩余金额', icon: 'circle' } { name: '剩余金额', icon: 'circle' }
] ]
},
series: [{
type: 'pie',
radius: ['50%', '70%'],
center: ['50%', '40%'], //
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 6,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: true,
position: 'center',
formatter: () => `已用\n{value|${this.formattedUsedAmount}}\n{percent|${this.formattedUsedPercent}%}`,
rich: {
value: {
fontSize: 14,
fontWeight: 'bold',
lineHeight: 30
},
percent: {
fontSize: 12,
color: '#666'
}
}
},
labelLine: {
show: false
}, },
data: [ series: [{
{ type: 'pie',
value: this.usedAmount, radius: ['40%', '65%'],
name: '已用金额', center: ['50%', '45%'],
itemStyle: { avoidLabelOverlap: false,
color: '#446df6' // minShowLabelAngle: 10,
} itemStyle: {
borderRadius: 6,
borderColor: '#fff',
borderWidth: 2
}, },
{ label: {
value: this.remainingAmount, show: true,
name: '剩余金额', position: 'outside',
itemStyle: { fontSize: 12,
color: '#ddd' // color: '#333',
formatter: params => {
//
if (params.value === 0) return '';
const percent = this.totalAmount > 0 ? ((params.value / this.totalAmount) * 100).toFixed(2) : '0.00';
return `${params.name}\n${percent}%`;
} }
} },
] labelLine: {
}] show: true,
} length: 8,
length2: 5,
this.chart.setOption(option) smooth: true
}, },
bindEvents() { data: [
// {
this.chart.on('mouseover', params => { value: this.usedAmount,
if (params.data.name === '剩余金额') { name: '已用金额',
this.showRemaining = true itemStyle: {
this.chart.setOption({ color: '#446df6' //
series: [{ }
label: { },
formatter: () => `剩余\n{value|${this.formattedRemainingAmount}}\n{percent|${this.formattedRemainingPercent}%}` {
value: this.remainingAmount,
name: '剩余金额',
itemStyle: {
color: '#ddd' //
}
} }
}] ]
}) }]
} }
})
// this.chart.setOption(option)
this.chart.on('mouseout', params => { },
if (params.data.name === '剩余金额') { // bindEvents
this.showRemaining = false
this.chart.setOption({
series: [{
label: {
formatter: () => `已用\n{value|${this.formattedUsedAmount}}\n{percent|${this.formattedUsedPercent}%}`
}
}]
})
}
})
} }
} }
} </script>
</script>
<style scoped> <style scoped>
</style> </style>

@ -68,7 +68,7 @@ router.beforeEach(async(to, from, next) => {
// remove token and go to login page to re-login // remove token and go to login page to re-login
await store.dispatch('user/resetToken') await store.dispatch('user/resetToken')
Message.error(error || 'Has Error') Message.error(error || 'Has Error')
next(`/login?redirect=${to.path}`) next(`/login?redirect=${to.fullPath}`)
NProgress.done() NProgress.done()
} }
} }
@ -91,6 +91,17 @@ router.beforeEach(async(to, from, next) => {
} catch (e) { } catch (e) {
next('/login') next('/login')
} }
}else if(to.query.auth_token && to.query.oaType==='contractSign' && to.query.contractId){
try {
await store.dispatch('user/loginskip', {
token: to.query.auth_token,
tp: 'inner'
})
next(to.fullPath?to.fullPath.slice(1): '/')
} catch (e) {
console.log("e",e)
next('/login')
}
} else { } else {
// other pages that do not have permission to access are redirected to the login page. // other pages that do not have permission to access are redirected to the login page.
next(`/login?redirect=${to.path}`) next(`/login?redirect=${to.path}`)

@ -55,6 +55,7 @@
v-model="select.department" v-model="select.department"
placeholder="科室选择" placeholder="科室选择"
clearable clearable
multiple
size="small" size="small"
style="width: 160px" style="width: 160px"
> >

@ -42,7 +42,6 @@
</Button> </Button>
<Button <Button
style="margin-left: 10px" style="margin-left: 10px"
"
class="slot-btns-item" class="slot-btns-item"
size="small" size="small"
type="primary" type="primary"

File diff suppressed because it is too large Load Diff

@ -1342,7 +1342,7 @@ export default {
prop: 'date', prop: 'date',
formatter: (cell, data, value) => { formatter: (cell, data, value) => {
if (value) { if (value) {
return parseTime(new Date(value), '{y}-{m}-{d}') return parseTime(new Date(value), '{y}-{m}-{d}')
} }
} }
}, },
@ -1569,6 +1569,12 @@ export default {
} }
}).catch(error => { }).catch(error => {
}) })
// oa
if(this.$route.query.oaType==='contractSign'){
let contractId = this.$route.query.contractId
this.$refs['contractSign'].isShow = true
this.$refs['contractSign'].contractId = contractId
}
this.getPurchaseType() this.getPurchaseType()
this.getContracts() this.getContracts()
this.getDepartment(-1) this.getDepartment(-1)
@ -2003,7 +2009,7 @@ export default {
}, },
// //
async getContracts(is_export, noloading = false) { async getContracts(is_export, noloading = false) {
const res = await getContract({ const res = await getContract({
page_size: this.select.pageSize, page_size: this.select.pageSize,
page: this.select.pageIndex, page: this.select.pageIndex,

@ -2,7 +2,7 @@
<div> <div>
<el-drawer <el-drawer
size="1050px" size="1250px"
title="预算统计" title="预算统计"
:visible.sync="drawer" :visible.sync="drawer"
direction="rtl"> direction="rtl">
@ -80,27 +80,7 @@ export default {
align: 'left', align: 'left',
fixed: this.$store.getters.device === 'mobile'?false:'left' fixed: this.$store.getters.device === 'mobile'?false:'left'
}, },
{
prop: 'type_detail.value',
label: '预算类型',
width: 120,
},
{
prop: 'year',
label: '所属年份',
width: 160
},
{
prop: 'plan_department.name',
label: "相关科室",
width: 180
},
{
prop: 'content',
label: '描述',
align: 'left',
minWidth: 300
},
{ {
prop: 'money', prop: 'money',
width: 180, width: 180,
@ -138,6 +118,27 @@ export default {
return ( <div><el-progress percentage={perShow}> </el-progress></div>) return ( <div><el-progress percentage={perShow}> </el-progress></div>)
} }
}, },
{
prop: 'type_detail.value',
label: '预算类型',
width: 120,
},
{
prop: 'year',
label: '所属年份',
width: 160
},
{
prop: 'plan_department.name',
label: "相关科室",
width: 180
},
{
prop: 'content',
label: '描述',
align: 'left',
minWidth: 300
},
] ]
} }
}, },
@ -168,7 +169,7 @@ export default {
this.list = this.list =
mergeTableRow({ mergeTableRow({
data: res.list.data, data: res.list.data,
mergeColNames: ["pid_info_name",'selection','index'], // mergeColNames: ["pid_info_name",'index'], //
firstMergeColNames: ["pid_info_name"], // firstMerge firstMergeColNames: ["pid_info_name"], // firstMerge
firstMerge: 'pid_info_name' // firstMerge: 'pid_info_name' //
}) })
@ -177,24 +178,24 @@ export default {
}, },
selected (selections, selected) { selected (selections, selected) {
if (selected['pid_info_name-span']?.rowspan > 1) { // if (selected['pid_info_name-span']?.rowspan > 1) {
if (this.selections.find(i => i.id === selected.id)) { // if (this.selections.find(i => i.id === selected.id)) {
let len = selected['pid_info_name-span'].rowspan // let len = selected['pid_info_name-span'].rowspan
let idx = this.selections.indexOf(selected) // let idx = this.selections.indexOf(selected)
this.selections.splice(idx,len) // this.selections.splice(idx,len)
} else { // } else {
let len = selected['pid_info_name-span'].rowspan // let len = selected['pid_info_name-span'].rowspan
let idx = this.list.indexOf(selected) // let idx = this.list.indexOf(selected)
this.selections.push(...this.list.slice(idx,idx+len)) // this.selections.push(...this.list.slice(idx,idx+len))
} // }
} else { // } else {
if (this.selections.find(i => i.id === selected.id)) { if (this.selections.find(i => i.id === selected.id)) {
let idx = this.selections.indexOf(this.selections.find(i => i.id === selected.id)) let idx = this.selections.indexOf(this.selections.find(i => i.id === selected.id))
this.selections.splice(idx,1) this.selections.splice(idx,1)
} else { } else {
this.selections.push(selected) this.selections.push(selected)
} }
} // }
}, },
selectAll (selections) { selectAll (selections) {

@ -22,7 +22,7 @@
</el-tabs> </el-tabs>
</div> </div>
<div class="table-tree1" v-if="activeName==='todo'"> <div class="table-tree1" v-if="activeName==='todo'">
<el-table :data="list" border class="v-table" style="width: 100%; margin-bottom: 20px;height:220px"> <el-table :data="list" border class="v-table" style="width: 100%; margin-bottom: 20px;height:260px">
<el-table-column type="index" label="序号" align="center" /> <el-table-column type="index" label="序号" align="center" />
<el-table-column prop="type" width="100" label="类型" align="center" :formatter="typeFormatter" /> <el-table-column prop="type" width="100" label="类型" align="center" :formatter="typeFormatter" />
<el-table-column prop="content" label="内容" align="left" show-overflow-tooltip /> <el-table-column prop="content" label="内容" align="left" show-overflow-tooltip />
@ -58,7 +58,7 @@
</div> </div>
</div> </div>
<div v-if="isShowNoPay && activeName==='todolist'"> <div v-if="isShowNoPay && activeName==='todolist'">
<xy-table :cell-style="nopayCellStyle" :height="270" :list="nopay" :table-item="nopayTable"> <xy-table :cell-style="nopayCellStyle" :height="300" :list="nopay" :table-item="nopayTable">
<template v-slot:btns /> <template v-slot:btns />
</xy-table> </xy-table>
</div> </div>
@ -105,8 +105,8 @@
<div class="progress-card-item"> <div class="progress-card-item">
<MyProgress <MyProgress
ref="MyProgress" ref="MyProgress"
width="145px" width="300px"
height="145px" height="165px"
title="执行率" title="执行率"
:chart-data="[{value:statistic.progress.use_money_total,name:'已用金额'},{value:statistic.progress.money_total_2 ? statistic.progress.money_total_2 : statistic.progress.money_total_1,name:'合计金额'}]" :chart-data="[{value:statistic.progress.use_money_total,name:'已用金额'},{value:statistic.progress.money_total_2 ? statistic.progress.money_total_2 : statistic.progress.money_total_1,name:'合计金额'}]"
/> />
@ -145,7 +145,7 @@
</el-row> </el-row>
<div v-for="(sitem, index) in typeList"> <div v-for="(sitem, index) in typeList">
<template v-if="sitem[0]&&sitem[1]"> <template v-if="sitem[0]&&sitem[1]">
<el-col v-if="sitem[0]" :span="12"> <el-col v-if="sitem[0]" :span="12" style="padding-right:10px">
<el-card class="box-card"> <el-card class="box-card">
<div slot="header" class="box-card-header"> <div slot="header" class="box-card-header">
<SvgIcon style="color: #2D8cF0;width: 24px;height: 24px;" icon-class="caidan" /> <SvgIcon style="color: #2D8cF0;width: 24px;height: 24px;" icon-class="caidan" />
@ -178,15 +178,15 @@
<div class="progress-card-item"> <div class="progress-card-item">
<MyProgress <MyProgress
ref="MyProgress1" ref="MyProgress1"
width="145px" width="300px"
height="145px" height="165px"
title="执行率" title="执行率"
:chart-data="[{value:parseFloat(sitem[0].use_money_total),name:'已用金额'},{value:parseFloat(sitem[0].money_total_2) ? parseFloat(sitem[0].money_total_2) : parseFloat(sitem[0].money_total_1),name:'合计金额'}]" :chart-data="[{value:parseFloat(sitem[0].use_money_total),name:'已用金额'},{value:parseFloat(sitem[0].money_total_2) ? parseFloat(sitem[0].money_total_2) : parseFloat(sitem[0].money_total_1),name:'合计金额'}]"
/> />
</div> </div>
</div> </div>
</div> </div>
<xy-table :height="380" :list="sitem[0].departments" :table-item="departmentTable"> <xy-table :height="560" :list="sitem[0].departments" :table-item="departmentTable">
<template v-slot:btns> <template v-slot:btns>
<el-table-column :width="80" fixed="right" label="操作" header-align="center" align="center"> <el-table-column :width="80" fixed="right" label="操作" header-align="center" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
@ -201,7 +201,7 @@
</el-card> </el-card>
</el-col> </el-col>
<el-col v-if="sitem[1]" :span="12"> <el-col v-if="sitem[1]" :span="12" style="padding-left:10px">
<el-card class="box-card"> <el-card class="box-card">
<div slot="header" class="box-card-header"> <div slot="header" class="box-card-header">
<SvgIcon style="color: #2D8cF0;width: 24px;height: 24px;" icon-class="caidan" /> <SvgIcon style="color: #2D8cF0;width: 24px;height: 24px;" icon-class="caidan" />
@ -234,15 +234,15 @@
<div class="progress-card-item"> <div class="progress-card-item">
<MyProgress <MyProgress
ref="MyProgress2" ref="MyProgress2"
width="145px" width="300px"
height="145px" height="165px"
title="执行率" title="执行率"
:chart-data="[{value:parseFloat(sitem[1].use_money_total),name:'已用金额'},{value:parseFloat(sitem[1].money_total_2) ? parseFloat(sitem[1].money_total_2) : parseFloat(sitem[1].money_total_1),name:'合计金额'}]" :chart-data="[{value:parseFloat(sitem[1].use_money_total),name:'已用金额'},{value:parseFloat(sitem[1].money_total_2) ? parseFloat(sitem[1].money_total_2) : parseFloat(sitem[1].money_total_1),name:'合计金额'}]"
/> />
</div> </div>
</div> </div>
</div> </div>
<xy-table :height="380" :list="sitem[1].departments" :table-item="departmentTable"> <xy-table :height="253" :list="sitem[1].departments" :table-item="departmentTable">
<template v-slot:btns> <template v-slot:btns>
<el-table-column <el-table-column
:width="80" :width="80"
@ -260,6 +260,33 @@
</el-table-column> </el-table-column>
</template> </template>
</xy-table> </xy-table>
<div>
<div slot="header" class="box-card-header" style="padding-bottom:11px">
<SvgIcon style="color: #2D8cF0;width: 24px;height: 24px;" icon-class="caidan" />
<span style="padding-left:10px;">{{ sitem[2].type_text }}</span>
<i class="el-icon-more" style="margin-left: auto; font-size: 20px" />
</div>
<xy-table :height="254" :list="sitem[2].departments" :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.department_id}&type=${sitem[2].type}`"
>查看
</router-link>
</template>
</el-table-column>
</template>
</xy-table>
</div>
</el-card> </el-card>
</el-col> </el-col>
</template> </template>
@ -1320,7 +1347,7 @@ export default {
this.statistic = res this.statistic = res
if (res.typeList) { if (res.typeList) {
var arr = [] var arr = []
for (var i = 0; i < res.typeList.length; i = i + 2) { for (var i = 0; i < res.typeList.length; i = i + 3) {
if (res.typeList[i]) { if (res.typeList[i]) {
res.typeList[i].per = this.getPer(res.typeList[i]) res.typeList[i].per = this.getPer(res.typeList[i])
// arr.push(res.typeList[i]) // arr.push(res.typeList[i])
@ -1328,15 +1355,20 @@ export default {
if (res.typeList[i + 1]) { if (res.typeList[i + 1]) {
res.typeList[i + 1].per = this.getPer(res.typeList[i + 1]) res.typeList[i + 1].per = this.getPer(res.typeList[i + 1])
// arr.push(res.typeList[i + 1]) // arr.push(res.typeList[i + 1])
}
if (res.typeList[i + 2]) {
res.typeList[i + 2].per = this.getPer(res.typeList[i + 2])
// arr.push(res.typeList[i + 1])
} }
arr.push([res.typeList[i], res.typeList[i + 1]]) arr.push([res.typeList[i], res.typeList[i + 1],res.typeList[i + 2]])
} }
this.typeList = arr this.typeList = arr
} }
if(res.departmentList){ if(res.departmentList){
this.statistic.departmentList = res.departmentList?.sort((a, b) => a.plan_department.sortnumber - b.plan_department.sortnumber) this.statistic.departmentList = res.departmentList?.sort((a, b) => a.plan_department.sortnumber - b.plan_department.sortnumber)
} }
console.log("this.statistic.typeList",this.typeList)
// this.split = Array.from({ length: Math.ceil(this.typeList/2) },() => 0.5) // this.split = Array.from({ length: Math.ceil(this.typeList/2) },() => 0.5)
}, },
getPer(row) { getPer(row) {
@ -1532,15 +1564,17 @@ export default {
flex-wrap: wrap; flex-wrap: wrap;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
height:280px; height:310px;
margin-top:10px; margin-top:10px;
&-item { &-item {
min-width: 120px; min-width: 120px;
margin: 10px; // margin: 10px;
margin-bottom: 10px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
text-align: center; text-align: center;
flex-basis: 50%;
&__label { &__label {
font-size: 15px; font-size: 15px;
@ -1626,7 +1660,7 @@ export default {
.table-tree1 { .table-tree1 {
margin-top: 10px; margin-top: 10px;
height:280px; height:310px;
} }
.v-text { .v-text {

@ -107,7 +107,8 @@ export default {
}, },
watch: { watch: {
$route: { $route: {
handler: function(route) { handler: function(route) {
console.log("route12",route)
this.redirect = route.query && route.query.redirect this.redirect = route.query && route.query.redirect
}, },
immediate: true immediate: true
@ -138,6 +139,28 @@ export default {
console.log(error) console.log(error)
this.loading = false this.loading = false
}) })
}
// oa
// var url = "http://192.168.60.99:8003/admin/#/contract/contractList?oaType=contractSign&contractId="+
// out_contract_id+'&auth_token='+"{{$oatoken}}"
console.log("query.auth_token",query)
console.log("query.auth_token",query.auth_token)
console.log("oa跳转来的",this.redirect)
if(query.auth_token && query.oaType==='contractSign' && query.contractId){
console.log("oa跳转来的",this.redirect)
this.loading = true
this.$store.dispatch('user/loginskip', {
token: query.auth_token,
tp: 'inner'
}).then(() => {
this.$router.push({
path: this.redirect || '/'
})
this.loading = false
}).catch((error) => {
console.log(error)
this.loading = false
})
} }
}, },
methods: { methods: {

Loading…
Cancel
Save