568 lines
23 KiB
Python
568 lines
23 KiB
Python
<template>
|
||
<div class="app-container">
|
||
<el-card>
|
||
<el-row :gutter="6">
|
||
<el-date-picker
|
||
v-model="listQuery.year"
|
||
type="year"
|
||
placeholder="选择年"
|
||
value-format="yyyy"
|
||
style="width:200px"
|
||
>
|
||
</el-date-picker>
|
||
<el-button
|
||
class="filter-item"
|
||
type="primary"
|
||
icon="el-icon-search"
|
||
@click="handleFilter"
|
||
>查看</el-button>
|
||
<el-button
|
||
type="primary"
|
||
@click="handlePrint"
|
||
>打印</el-button
|
||
>
|
||
<el-button
|
||
type="primary"
|
||
@click="exportExcel"
|
||
>导出</el-button
|
||
>
|
||
</el-row>
|
||
</el-card>
|
||
<el-card style="margin-top:10px">
|
||
<div ref="print" id="myReport" class="printContainers">
|
||
<h3 style="text-align: center;">{{ fileName }}</h3>
|
||
<p v-if="fileName!==''" style="text-align: center;">{{ listQuery.task2__year }}年 </p>
|
||
<!-- 5个单位目标 -->
|
||
<el-row id="echartsContainer">
|
||
<el-col class="chartsWraps">
|
||
<div id="main" style="width:100%;height:700px;margin-left: 10px;" ref="chart"></div>
|
||
</el-col>
|
||
<el-col class="chartsWraps">
|
||
<div id="main2" style="width:100%;height:700px;margin-left: 10px;" ref="chart2"></div>
|
||
</el-col>
|
||
<el-col class="chartsWraps">
|
||
<div id="main3" style="width:100%;height:700px;margin-left: 10px;" ref="chart3"></div>
|
||
</el-col>
|
||
<el-col class="chartsWraps">
|
||
<div id="main4" style="width:100%;height:700px;margin-left: 10px;" ref="chart4"></div>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
</el-card>
|
||
</div>
|
||
</template>
|
||
<script>
|
||
import { taskAnalyse } from "@/api/task";
|
||
import checkPermission from "@/utils/permission";
|
||
import * as echarts from 'echarts';
|
||
import ExcelJS from 'exceljs'; // 引入exceljs, 用于生成excel文件
|
||
import { saveAs } from 'file-saver'
|
||
export default {
|
||
data() {
|
||
return {
|
||
timeStamp:0,
|
||
listQuery:{
|
||
year:'',
|
||
dept_type_name:'2级公司'
|
||
},
|
||
xaxis:[],
|
||
deptName:'',
|
||
fileName:'',
|
||
option:{},
|
||
option1:{},
|
||
option2:{},
|
||
option3:{},
|
||
option4:{},
|
||
};
|
||
},
|
||
mounted() {
|
||
var myDate = new Date();
|
||
this.listQuery.year = myDate.getFullYear();
|
||
this.setOption();
|
||
this.handleFilter();
|
||
this.option = {
|
||
//标题
|
||
title: {
|
||
text: '',
|
||
// subtext: '小标题',
|
||
x: 'center',
|
||
top:'3%'
|
||
},
|
||
tooltip: {
|
||
trigger:"axis",
|
||
axisPointer: {
|
||
type: 'shadow'
|
||
},
|
||
},
|
||
legend: {
|
||
data:['单位完成值','单位单位目标',{name:'集团单位目标',itemStyle:{opacity:0}}],
|
||
right:'10%',
|
||
top:'3%'
|
||
},
|
||
grid: {
|
||
left: '1%',
|
||
right: '2%',
|
||
bottom: '25%',
|
||
top: '12%',
|
||
containLabel: true
|
||
},
|
||
xAxis: [
|
||
{
|
||
axisLabel: {
|
||
interval: 'auto',
|
||
color:'#000000',
|
||
rotate: 45 //设置倾斜角度,数值 可设置 正负 两种,
|
||
},
|
||
type: 'category',
|
||
data: [],
|
||
},
|
||
{
|
||
type: 'category',
|
||
position: 'bottom',
|
||
offset: 180,
|
||
axisPointer: {
|
||
type: 'none',
|
||
},
|
||
axisTick: {
|
||
show: true,
|
||
length: 35,
|
||
inside: true,
|
||
},
|
||
axisLine: {
|
||
show: true,
|
||
lineStyle: {
|
||
color: '#999',
|
||
},
|
||
},
|
||
axisLabel: {
|
||
inside: true,
|
||
textStyle: {
|
||
fontSize: '14',
|
||
},
|
||
interval: 0,
|
||
},
|
||
data: [],
|
||
},
|
||
{
|
||
position: 'bottom',
|
||
offset: 145,
|
||
axisPointer: {
|
||
type: 'none',
|
||
},
|
||
axisTick: {
|
||
show: true,
|
||
length: 35,
|
||
inside: true,
|
||
},
|
||
axisLine: {
|
||
show: true,
|
||
lineStyle: {
|
||
color: '#999',
|
||
},
|
||
},
|
||
axisLabel: {
|
||
inside: true,
|
||
textStyle: {
|
||
fontSize: '14',
|
||
},
|
||
interval: 0,
|
||
},
|
||
data: [],
|
||
},
|
||
{
|
||
position: 'bottom',
|
||
offset: 110,
|
||
axisPointer: {
|
||
type: 'none',
|
||
},
|
||
axisTick: {
|
||
show: true,
|
||
length: 35,
|
||
inside: true,
|
||
},
|
||
axisLine: {
|
||
show: true,
|
||
lineStyle: {
|
||
color: '#999',
|
||
},
|
||
},
|
||
axisLabel: {
|
||
inside: true,
|
||
textStyle: {
|
||
fontSize: '14',
|
||
},
|
||
interval: 0,
|
||
},
|
||
data: [],
|
||
},
|
||
{
|
||
position: 'bottom',
|
||
offset: 75,
|
||
axisPointer: {
|
||
type: 'none',
|
||
},
|
||
axisTick: {
|
||
show: true,
|
||
length: 35,
|
||
inside: true,
|
||
},
|
||
axisLine: {
|
||
show: true,
|
||
lineStyle: {
|
||
color: '#999',
|
||
},
|
||
},
|
||
axisLabel: {
|
||
inside: true,
|
||
textStyle: {
|
||
fontSize: '14',
|
||
},
|
||
interval: 0,
|
||
},
|
||
data: [],
|
||
}
|
||
],
|
||
color:['#c9caca','#007dcd','#000000'],
|
||
yAxis: {
|
||
type: 'value',
|
||
axisLabel:{
|
||
formatter:"{value}%"
|
||
},
|
||
scale:true,
|
||
min:85,
|
||
max:100,
|
||
},
|
||
series: [
|
||
{
|
||
name: '单位完成值',
|
||
type: 'bar',
|
||
barGap: 0,
|
||
barWidth:10,
|
||
data: [],
|
||
label: {
|
||
show: true,
|
||
position: 'top'
|
||
},
|
||
markLine : {
|
||
symbol:"none",
|
||
label: {
|
||
position: "end", //将警示值放在哪个位置,三个值“start”,"middle","end" 开始 中点 结束
|
||
},
|
||
data :[
|
||
{
|
||
silent:false, //鼠标悬停事件 true没有,false有
|
||
lineStyle:{ //警戒线的样式 ,虚实 颜色
|
||
type:"solid",
|
||
color:"#000000",
|
||
},
|
||
label:{
|
||
position:'end',
|
||
formatter:'{c}',
|
||
color:"#000000",
|
||
fontSize:'14'
|
||
},
|
||
name:'',
|
||
yAxis:99 // 警戒线的标注值,可以有多个yAxis,多条警示线 或者采用 {type : 'average', name: '平均值'},type值有 max min average,分为最大,最小,平均值
|
||
}
|
||
]
|
||
}
|
||
},
|
||
{
|
||
name: '单位单位目标',
|
||
type: 'bar',
|
||
barWidth:10,
|
||
label: {
|
||
show: true,
|
||
position: 'top'
|
||
},
|
||
data: []
|
||
},
|
||
{
|
||
name: '集团单位目标',
|
||
type: 'line',
|
||
data: []
|
||
}
|
||
],
|
||
};
|
||
|
||
},
|
||
methods: {
|
||
handlePrint() {
|
||
this.$PRINT('#myReport');
|
||
},
|
||
setOption(){
|
||
this.barChart1 = echarts.init(document.getElementById('main'));
|
||
this.barChart2 = echarts.init(document.getElementById('main2'));
|
||
this.barChart3 = echarts.init(document.getElementById('main3'));
|
||
this.barChart4 = echarts.init(document.getElementById('main4'));
|
||
},
|
||
checkPermission,
|
||
handleFilter(){
|
||
let that = this;
|
||
function compare(property) {
|
||
return function (a, b) {
|
||
return b[property]-a[property];
|
||
}
|
||
}
|
||
taskAnalyse(that.listQuery).then(res=>{
|
||
console.log(res)
|
||
let data = res.data;
|
||
let xaxis1 = [''],data1 = [],data12=[],
|
||
xaxis2 = [''],data2 = [],data22=[],
|
||
xaxis3 = [''],data3 = [],data32=[],
|
||
xaxis4 = [''],data4 = [],data42=[];
|
||
let minNumber1=0,minNumber2=0,minNumber3=0,minNumber4=0;
|
||
let markLine1 = 0,markLine2=0,markLine3=0,markLine4=0;
|
||
let sortedArr1 = data.sort(compare("报告证书合格率"));
|
||
sortedArr1.forEach(item1=>{
|
||
xaxis1.push(item1.单位)
|
||
data1.push(item1.报告证书合格率)
|
||
data12.push(item1.报告证书合格率设定值)
|
||
})
|
||
markLine1 = sortedArr1[0].报告证书合格率基础值;
|
||
let sortedArr2 = data.sort(compare("报告证书及时率"));
|
||
sortedArr2.forEach(item2=>{
|
||
xaxis2.push(item2.单位)
|
||
data2.push(item2.报告证书及时率)
|
||
data22.push(item2.报告证书及时率设定值)
|
||
})
|
||
markLine2 = sortedArr2[0].报告证书及时率基础值;
|
||
let sortedArr3 = data.sort(compare("能力验证满意率"));
|
||
sortedArr3.forEach(item3=>{
|
||
xaxis3.push(item3.单位)
|
||
data3.push(item3.能力验证满意率)
|
||
data32.push(item3.能力验证满意率设定值)
|
||
})
|
||
markLine3 = sortedArr3[0].能力验证满意率基础值;
|
||
let sortedArr4 = data.sort(compare("客户投诉处理满意率"));
|
||
sortedArr4.forEach(item4=>{
|
||
xaxis4.push(item4.单位)
|
||
data4.push(item4.客户投诉处理满意率)
|
||
data42.push(item4.客户投诉处理满意率设定值)
|
||
})
|
||
minNumber1 =Math.min(...data1)
|
||
minNumber1 = Math.floor(minNumber1);
|
||
if(minNumber1>0){
|
||
minNumber1 = minNumber1-1;
|
||
}
|
||
minNumber2 =Math.min(...data2)
|
||
minNumber2 = Math.floor(minNumber2)
|
||
if(minNumber2>0){
|
||
minNumber2 = minNumber2-1;
|
||
}
|
||
minNumber3 =Math.min(...data3)
|
||
minNumber3 = Math.floor(minNumber3)
|
||
if(minNumber3>0){
|
||
minNumber3 = minNumber3-1;
|
||
}
|
||
minNumber4 =Math.min(...data4)
|
||
minNumber4 = Math.floor(minNumber4)
|
||
if(minNumber4>0){
|
||
minNumber4 = minNumber4-1;
|
||
}
|
||
markLine4 = sortedArr4[0].客户投诉处理满意率基础值;
|
||
|
||
function tofixed1(item){
|
||
if(item!==null){
|
||
let item1 = item.toFixed(1)
|
||
return item1
|
||
}else{
|
||
return ''
|
||
}
|
||
}
|
||
function tofixed2(item){
|
||
let item0=item+'';
|
||
if(item!==null){
|
||
if(item0.indexOf('.')>-1){
|
||
let item1 = item.toFixed(2)
|
||
return item1
|
||
}else{
|
||
return item
|
||
}
|
||
}else{
|
||
return ''
|
||
}
|
||
}
|
||
let arr1 = [''],arr2=[''],arr3=[''],arr4=[''],
|
||
arr12 = [''],arr22=[''],arr32=[''],arr42=[''],
|
||
markarr1 = ['集团目标'],markarr2=['集团目标'],markarr3=['集团目标'],markarr4=['集团目标'];
|
||
for(let i=0;i<data1.length;i++){
|
||
markarr1.push(markLine1.toFixed(1))
|
||
markarr2.push(markLine2.toFixed(1))
|
||
markarr3.push(markLine3.toFixed(1))
|
||
markarr4.push(markLine4.toFixed(1))
|
||
}
|
||
let option1 =that.option;
|
||
let option2 =that.option;
|
||
let option3=that.option;
|
||
let option4= that.option;
|
||
data1.forEach(item=>{
|
||
let item1 = tofixed2(item)
|
||
arr12.push(item1)
|
||
})
|
||
data12.forEach(item=>{
|
||
let item2 = tofixed1(item)
|
||
arr1.push(item2)
|
||
})
|
||
let xAxis12 = arr1;xAxis12[0]='单位目标';
|
||
let xAxis13 = arr12;xAxis13[0]='完成值';
|
||
option1.yAxis.min = minNumber1;
|
||
option1.xAxis[0].data = xaxis1;
|
||
option1.xAxis[1].data =markarr1;//集团单位目标
|
||
option1.xAxis[2].data = xAxis12;//部门单位目标
|
||
option1.xAxis[3].data = xAxis13;//部门完成值
|
||
option1.series[0].data = arr12;//部门完成值
|
||
option1.series[1].data = arr1;//单位单位目标
|
||
option1.title.text = '报告/证书合格率';
|
||
option1.series[0].markLine.data[0].yAxis = markLine1.toFixed(1);
|
||
that.barChart1.clear();
|
||
that.barChart1.setOption(option1);
|
||
data2.forEach(item=>{
|
||
let item1 = tofixed2(item)
|
||
arr22.push(item1)
|
||
})
|
||
data22.forEach(item=>{
|
||
let item2 = tofixed1(item)
|
||
arr2.push(item2)
|
||
})
|
||
let xAxis22 = arr2;xAxis22[0]='单位目标';
|
||
let xAxis23 = arr22;xAxis23[0]='完成值';
|
||
option2.yAxis.min = minNumber2;
|
||
option2.xAxis[0].data = xaxis2;
|
||
option2.xAxis[1].data =markarr2;//集团单位目标
|
||
option2.xAxis[2].data = xAxis22;//部门单位目标
|
||
option2.xAxis[3].data = xAxis23;//部门完成值
|
||
option2.series[0].data = arr22;
|
||
option2.series[1].data = arr2;
|
||
option2.title.text = '报告/证书及时率';
|
||
option2.series[0].markLine.data[0].yAxis = markLine2.toFixed(1);
|
||
that.barChart2.clear();
|
||
that.barChart2.setOption(option2);
|
||
data3.forEach(item=>{
|
||
let item1 = tofixed2(item)
|
||
arr32.push(item1)
|
||
})
|
||
data32.forEach(item=>{
|
||
let item2 = tofixed1(item)
|
||
arr3.push(item2)
|
||
})
|
||
let xAxis32 = arr3;xAxis32[0]='单位目标';
|
||
let xAxis33 = arr32;xAxis33[0]='完成值';
|
||
option3.yAxis.min = minNumber3;
|
||
option3.xAxis[0].data = xaxis3;
|
||
option3.xAxis[1].data =markarr3;//集团单位目标
|
||
option3.xAxis[2].data = xAxis32;//部门单位目标
|
||
option3.xAxis[3].data = xAxis33;//部门完成值
|
||
option3.series[0].data = arr32;
|
||
option3.series[1].data = arr3;
|
||
option3.title.text = '能力验证满意率';
|
||
option3.series[0].markLine.data[0].yAxis = markLine3.toFixed(1);
|
||
that.barChart3.clear();
|
||
that.barChart3.setOption(option3);
|
||
data4.forEach(item=>{
|
||
let item1 = tofixed2(item)
|
||
arr42.push(item1)
|
||
})
|
||
data42.forEach(item=>{
|
||
let item2 = tofixed1(item)
|
||
arr4.push(item2)
|
||
})
|
||
let xAxis42 = arr4;xAxis42[0]='单位目标';
|
||
let xAxis43 = arr42;xAxis43[0]='完成值';
|
||
option4.yAxis.min = minNumber4;
|
||
option4.xAxis[0].data = xaxis4;
|
||
option4.xAxis[1].data =markarr4;//集团单位目标
|
||
option4.xAxis[2].data = xAxis42;//部门单位目标
|
||
option4.xAxis[3].data = xAxis43;//部门完成值
|
||
option4.series[0].data = arr42;
|
||
option4.series[1].data = arr4;
|
||
option4.title.text = '客户投诉处理满意率';
|
||
option4.series[0].markLine.data[0].yAxis = markLine4.toFixed(1);
|
||
that.barChart4.clear();
|
||
that.barChart4.setOption(option4);
|
||
})
|
||
},
|
||
exportExcel() {
|
||
const workbook = new ExcelJS.Workbook(); // 创建工作簿
|
||
const worksheet = workbook.addWorksheet('Sheet1'); // 添加工作表
|
||
|
||
const chart = echarts.getInstanceByDom(this.$refs.chart) // 获取图表实例
|
||
const base64Image = chart.getDataURL({
|
||
pixelRatio: 2, // 导出图片的分辨率比例,默认为1,即图片的分辨率为屏幕分辨率的一倍
|
||
backgroundColor: '#fff' // 导出图片的背景色
|
||
})
|
||
let image= workbook.addImage({ // 添加图片
|
||
base64: base64Image, // 图片的base64编码
|
||
extension: 'png' // 图片的扩展名
|
||
});
|
||
worksheet.addImage(image, 'A1:AB35'); // 将图片添加到工作表中
|
||
|
||
const chart2 = echarts.getInstanceByDom(this.$refs.chart2)
|
||
const base64Image2 = chart2.getDataURL({
|
||
pixelRatio: 2,
|
||
backgroundColor: '#fff'
|
||
})
|
||
let image2= workbook.addImage({
|
||
base64: base64Image2,
|
||
extension: 'png'
|
||
});
|
||
worksheet.addImage(image2, 'A36:AB70');
|
||
|
||
const chart3 = echarts.getInstanceByDom(this.$refs.chart3)
|
||
const base64Image3 = chart3.getDataURL({
|
||
pixelRatio: 2,
|
||
backgroundColor: '#fff'
|
||
})
|
||
let image3= workbook.addImage({
|
||
base64: base64Image3,
|
||
extension: 'png'
|
||
});
|
||
worksheet.addImage(image3, 'A71:AB105');
|
||
const chart4 = echarts.getInstanceByDom(this.$refs.chart4)
|
||
const base64Image4 = chart4.getDataURL({
|
||
pixelRatio: 2,
|
||
backgroundColor: '#fff'
|
||
})
|
||
let image4= workbook.addImage({
|
||
base64: base64Image4,
|
||
extension: 'png'
|
||
});
|
||
worksheet.addImage(image4, 'A106:AB140');
|
||
workbook.xlsx.writeBuffer().then(function (buffer) { // 生成excel文件的二进制数据
|
||
saveAs.saveAs(new Blob([buffer], { // 生成Blob对象
|
||
type: 'application/octet-stream' // 指定文件的MIME类型
|
||
}), 'xchart.xlsx'); // 指定文件名
|
||
});
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
<style scoped>
|
||
#numTable,#echartsContainer{
|
||
/* margin-left: 37px; */
|
||
width: 100%;
|
||
}
|
||
#echartsContainer{
|
||
margin-left: 0;
|
||
}
|
||
#numTable td{
|
||
height: 32px;
|
||
padding-left: 5px;
|
||
}
|
||
.numCell{
|
||
width: 80px;
|
||
}
|
||
.numCell.numCell_last{
|
||
width: 100px;
|
||
}
|
||
#echartsContainer{
|
||
margin-top: 20px;
|
||
}
|
||
.chartsWraps{
|
||
width: 99%;
|
||
height: fit-content;
|
||
overflow-y: hidden;
|
||
overflow-x: scroll;
|
||
border-top: 1px solid #eeeeee;
|
||
}
|
||
</style> |