Authored by 王涛

Merge branch 'master-joke' into 'master'

chore:浙江乙方运维-乙方评估页面开发,禅道#2419

chore:浙江乙方运维-乙方评估页面开发,禅道#2419

See merge request !1107
<div style="padding: 0px 10px 0px 0px;">
<el-row :gutter="5" style="padding: 0px 5px 0px 0px;">
<el-button-group>
<el-button v-for="(item,index) in labels" :type="yearType==index?'primary':''"
style="display: inline-block;margin: 0px" @click="yearSel(item,index)"
:label="label">{{item.name}}
</el-button>
</el-button-group>
</el-row>
<el-row :gutter="5">
<el-col :span="24" style="border: #eeeeee 1px solid">
<el-row :gutter="5">
<el-col :span="24">
<el-descriptions
style="height: 60px;margin: 0px;padding-top: 20px;border-top: #eeeeee 1px solid;border-bottom: #eeeeee 1px solid"
:contentStyle="rowCenter" :labelStyle="rowCenter" title="" :column="4"
:data="summaryDatas">
<el-descriptions-item label="年度工单总数:">{{summaryDatas.total}}个</el-descriptions-item>
<el-descriptions-item label="年度已关闭工单总数:">{{summaryDatas.closedTotal}}个
</el-descriptions-item>
<el-descriptions-item label="年度已关闭工单平均用时:">{{summaryDatas.avgTotal}}天
</el-descriptions-item>
<el-descriptions-item label="年度已关闭工单省局环节平均用时:">{{summaryDatas.avgSjTotal}}天
</el-descriptions-item>
</el-descriptions>
</el-col>
</el-row>
<el-row :gutter="5">
<el-col :span="6">
<label style="float: left;line-height: 50px;padding-left: 10px"><span class="selYearAndMonth"
>{{selectYearAndMonth}}</span>工单分析图</label>
</el-col>
<el-col :span="18">
<div style="display: inline-block;float: right;margin-right: 5px">
月份筛选:
<el-button-group>
<el-button v-for="(item,index) in months" :type="monthType==index?'primary':''"
style="display: inline-block;margin: 5px 0px"
@click="monthSel(item,index)" :label="label">{{item.name}}
</el-button>
</el-button-group>
</div>
</el-col>
<el-col :span="24" style="margin: 0px 30px 0px 0px">
<el-row :gutter="5">
<!--受理环节-->
<el-col :span="9">
<div id="status"
:style="{'height' : height + 'px','border':'#eeeeee 1px solid','margin':'5px'}"></div>
</el-col>
<!--受理环节-->
<el-col :span="15">
<div id="tache"
:style="{'height' : height + 'px','border':'#eeeeee 1px solid','margin':'5px 5px 5px 0px'}"></div>
</el-col>
</el-row>
<el-row :gutter="5">
<el-col :span="24">
<div id="top10"
:style="{'height' : height + 'px','border':'#eeeeee 1px solid','margin':'5px'}"></div>
</el-col>
</el-row>
</el-col>
</el-row>
</el-col>
</el-row>
<!--弹框,展示各环节分析echarts-->
<cm-dialog title="分析" width="80%" :showDialogVisible="dialogVisible" :showFooter="false"
@hidedialog="showOrHideDia" :showOkBtn="false">
<el-row>
<!--受理环节-->
<el-col :span="12">
<div id="slSummary" style="height: 300px;margin: 10px;border: #eeeeee 1px solid"
class="diaEcharts"></div>
</el-col>
<!--分析环节-->
<el-col :span="12">
<div id="fxSummary" style="height: 300px;margin: 10px;border: #eeeeee 1px solid"
class="diaEcharts"></div>
</el-col>
</el-row>
<el-row>
<!--审批环节-->
<el-col :span="12">
<div id="spSummary" style="height: 300px;margin: 10px;border: #eeeeee 1px solid"
class="diaEcharts"></div>
</el-col>
<!--修改环节-->
<el-col :span="12">
<div id="xgSummary" style="height: 300px;margin: 10px;border: #eeeeee 1px solid"
class="diaEcharts"></div>
</el-col>
</el-row>
</cm-dialog>
</div>
\ No newline at end of file
... ...
export default {
name: 'projectPGIndex',
template: '',
components: {},
data() {
return {
rowCenter:{
"text-align":"center"
}
}
},
props: {
treeNode: {
type: Object,
default: {}
},
parentNode: {
type: Object,
default: {}
},
projectId: {
type: String,
default: ''
},
key: {
type: String,
default: ''
},
},
setup(props, {attrs, slots, emit}) {
let height = Vue.ref((window.innerHeight - 200)/2);
let dlgHeight = Vue.ref((window.innerHeight - 160)/3)
let width = Vue.ref(window.innerWidth * 0.6);
let fullWidth = Vue.ref(window.innerWidth - 200);
let dialogVisible = Vue.ref(false);
let title = Vue.ref('');
let labels = Vue.ref([]);
let months = Vue.ref([]);
let summaryDatas = Vue.ref({})
let selectMonth = Vue.ref('');
let selectYear = Vue.ref('');
let selectYearAndMonth = Vue.ref('');
let yearType = Vue.ref(0);
let monthType = Vue.ref(0);
const {proxy} = Vue.getCurrentInstance();
let yearSel = (item,index) => {
yearType.value = index
selectYear.value = item.value;
selectYearAndMonth.value = selectYear.value + '年'+ selectMonth.value + '月';
getSummary();
workOrderSummary();
workOrderClosedAvg();
unClosedTop10();
}
let monthSel = (item,index) =>{
monthType.value = index
selectMonth.value = item.value;
selectYearAndMonth.value = selectYear.value + '年'+ selectMonth.value + '月';
workOrderSummary();
workOrderClosedAvg();
unClosedTop10();
}
let getLabel = () => {
let years = [];
let nowYear = new Date().getFullYear();
selectYear.value = nowYear+'';
for (let i = nowYear; i >= 2022; i--) {
let yearObj = {};
yearObj.value = i+'';
yearObj.name = i+'年度';
years.push(yearObj);
}
labels.value = years;
}
let getMonth = () => {
let nowMonth = new Date().getUTCMonth()+1;
selectMonth.value = nowMonth;
let monthArr = [];
for (let i = 1; i <= 12 ; i++) {
let monthObj = {};
monthObj.value = i+'';
//设置默认月份
if (nowMonth == i){
monthType.value = i-1;
}
monthObj.name = (i)+'月';
monthArr.push(monthObj);
}
months.value = monthArr;
}
let getSelectYearAndMonth = () => {
let year = new Date().getFullYear();
let month = new Date().getUTCMonth()+1;
selectYearAndMonth.value = year+ '年'+month+'月'
}
// 已关闭事件审批环节平均用时柱状图
let workOrderClosedAvg = () => {
let time = getTime();
let url = "/api-web/bOpsProjectEvaluation/getWorkOrderClosedAvgEcharts?projectId="+props.projectId+"&time="+time;
proxy.$http.get(url, {}, function (res) {
if (res && res.success && res.data) {
let xDatas = [];
let yDatas = [];
res.data.forEach(item => {
xDatas.push(item.KEY);
yDatas.push(item.NUM);
})
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('tache'));
// 指定图表的配置项和数据
var option = {
toolbox: {
show : true,
feature : {
//敲黑板,重点!!!
myTool2:{//自定义按钮 danielinbiti,这里增加,selfbuttons可以随便取名字
show:true,//是否显示
title:'分析', //鼠标移动上去显示的文字
icon:'path://M525.4 721.2H330.9c-9 0-18.5-7.7-18.5-18.1V311c0-9 9.3-18.1 18.5-18.1h336.6c9.3 0 18.5 9.1 18.5 18.1v232.7c0 6 8.8 12.1 15 12.1 6.2 0 15-6 15-12.1V311c0-25.6-25.3-48.9-50.1-48.9h-335c-26.2 0-50.1 23.3-50.1 48.9v389.1c0 36.3 20 51.5 50.1 51.5h197.6c6.2 0 9.3-7.5 9.3-15.1 0-6-6.2-15.3-12.4-15.3zM378.8 580.6c-6.2 0-12.3 8.6-12.3 14.6s6.2 14.6 12.3 14.6h141.4c6.2 0 12.3-5.8 12.3-13.4 0.3-9.5-6.2-15.9-12.3-15.9H378.8z m251.6-91.2c0-6-6.2-14.6-12.3-14.6H375.7c-6.2 0-12.4 8.6-12.4 14.6s6.2 14.6 12.4 14.6h240.8c6.2 0.1 13.9-8.5 13.9-14.6z m-9.2-120.5H378.8c-6.2 0-12.3 8.6-12.3 14.6s6.2 14.6 12.3 14.6h240.8c7.7 0 13.9-8.6 13.9-14.6s-6.2-14.6-12.3-14.6z m119.4 376.6L709 714.1c9.2-12 14.6-27 14.6-43.2 0-39.4-32.1-71.4-71.8-71.4-39.7 0-71.8 32-71.8 71.4s32.1 71.4 71.8 71.4c16.3 0 31.3-5.4 43.4-14.5l31.6 31.5c3.8 3.8 10 3.8 13.8 0 3.8-3.8 3.8-10 0-13.8z m-88.8-23.6c-28.3 0-51.3-22.8-51.3-51s23-51 51.3-51c28.3 0 51.3 22.8 51.3 51s-23 51-51.3 51z', //图标
onclick:function() {//点击事件,这里的option1是chart的option信息
dialogEchartsLoad();
}
}
}
},
grid:{
right: '10%'
},
title: {
text: '已关闭事件审批环节平均用时',
textStyle:{
//文字颜色
//字体风格,'normal','italic','oblique'
fontStyle:'normal',
//字体粗细 'normal','bold','bolder','lighter',100 | 200 | 300 | 400...
fontWeight:'bold',
//字体系列
fontFamily:'sans-serif',
//字体大小
fontSize:14
}
},
xAxis: {
data: xDatas,
},
yAxis: {
name: "单位(天)",
},
tooltip: { // 鼠标悬浮提示框显示 X和Y 轴数据
backgroundColor: 'rgba(32, 33, 36,.7)',
borderColor: 'rgba(32, 33, 36,0.20)',
borderWidth: 1,
textStyle: { // 文字提示样式
color: '#fff',
fontSize: '12'
},
},
series: [
{
type: 'bar',
barWidth: '50%',
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#c0fbe3' },
{ offset: 0.5, color: '#aef8d4' },
{ offset: 1, color: '#aef8d4' }
])
},
data: yDatas
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
}
}, function () {
proxy.$global.showMsg('没有查询到记录!', 'warning');
});
}
let dialogEchartsLoad = () => {
showOrHideDia(true);
let time = getTime();
let url = "/api-web/bOpsProjectEvaluation/getWorkOrderClosedAvgDlgEcharts?projectId="+props.projectId+"&time="+time;
proxy.$http.get(url, {}, function (res) {
if (res && res.success && res.object) {
let slSummary = res.object.slSummary;
let fxSummary = res.object.fxSummary;
let spSummary = res.object.spSummary;
let xgSummary = res.object.xgSummary;
setOption(slSummary,'slSummary','受理环节');
setOption(fxSummary,'fxSummary','分析环节');
setOption(spSummary,'spSummary','审批环节');
setOption(xgSummary,'xgSummary','修改环节');
}
}, function () {
proxy.$global.showMsg('没有查询到记录!', 'warning');
});
}
let setOption = (summaryData,id,name) => {
let arr = [];
summaryData.forEach(item => {
arr.push({value: item.SERID, name: item.TIME})
})
// 指定图表的配置项和数据
var option = {
title: {
text: name,
left: 'center',
top: 'bottom',
textStyle:{
//文字颜色
//字体风格,'normal','italic','oblique'
fontStyle:'normal',
//字体粗细 'normal','bold','bolder','lighter',100 | 200 | 300 | 400...
fontWeight:'bold',
//字体系列
fontFamily:'sans-serif',
//字体大小
fontSize:14,
}
},
tooltip: {
triggeer: 'item',
formatter: '{b} : {c} ({d}%)'
},
series: [
{
name: '',
type: 'pie', // 设置图表类型为饼图
data: arr,
label: {
normal: {
show: true,
formatter: '{b}:{c}({d}%)'
},
labelLine: {show: true}
},
}
],
};
// 让 指定id 的 div 的_echarts_instance_属性值 为 空状态
document.getElementById(id).removeAttribute('_echarts_instance_');
var myChart = echarts.init(document.getElementById(id));
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
}
// 未处理完成时长Top10工单柱状图
let unClosedTop10 = () => {
let time = getTime();
let url = "/api-web/bOpsProjectEvaluation/getWorkOrderUnClosedTop10?projectId="+props.projectId+"&time="+time;
proxy.$http.get(url, {}, function (res) {
if (res && res.success && res.data) {
let xDatas = [];
let yDatas = [];
res.data.forEach(item => {
xDatas.push(item.DIVID);
yDatas.push(item.DAYS);
})
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('top10'));
// 指定图表的配置项和数据
var option = {
color: ['#6ec0cf'],
title: {
text: '未处理完成时长Top10工单',
textStyle:{
//文字颜色
//字体风格,'normal','italic','oblique'
fontStyle:'normal',
//字体粗细 'normal','bold','bolder','lighter',100 | 200 | 300 | 400...
fontWeight:'bold',
//字体系列
fontFamily:'sans-serif',
//字体大小
fontSize:14
}
},
xAxis: {
data: xDatas,
},
yAxis: {
name: "单位(天)",
},
tooltip: { // 鼠标悬浮提示框显示 X和Y 轴数据
backgroundColor: 'rgba(32, 33, 36,.7)',
borderColor: 'rgba(32, 33, 36,0.20)',
borderWidth: 1,
textStyle: { // 文字提示样式
color: '#fff',
fontSize: '12'
},
formatter: '{b} 工单时长 : {c} 天'
},
series: [
{
type: 'bar',
barWidth: '50%',
data: yDatas
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
}
}, function () {
proxy.$global.showMsg('没有查询到记录!', 'warning');
});
}
// 各状态工单量占比饼状图
let workOrderSummary = () => {
let time = getTime();
let url = "/api-web/bOpsProjectEvaluation/getWorkOrderAnalyseEcharts?projectId="+props.projectId+"&time="+time;
proxy.$http.get(url, {}, function (res) {
if (res && res.success && res.data) {
let arr = [];
res.data.forEach(item => {
arr.push({value: item.COUNT, name: item.WORKFLOWSTATUS2})
})
// 指定图表的配置项和数据
var option = {
color: ['#5979f6', '#79d6a6'],
title: {
text: '各状态工单量占比',
textStyle:{
//文字颜色
//字体风格,'normal','italic','oblique'
fontStyle:'normal',
//字体粗细 'normal','bold','bolder','lighter',100 | 200 | 300 | 400...
fontWeight:'bold',
//字体系列
fontFamily:'sans-serif',
//字体大小
fontSize:14
}
},
tooltip: {
triggeer: 'item',
formatter: '{b} : {c} ({d}%)'
},
series: [
{
name: '各状态工单量占比',
type: 'pie', // 设置图表类型为饼图
radius: '60%', // 饼图的半径,外半径为可视区尺寸(容器高宽中较小一项)的 55% 长度。
center: ["50%", "50%"],
data: arr,
label: {
normal: {
show: true,
formatter: '{b}:{c}({d}%)'
},
labelLine: {show: true}
},
}
],
};
var myChart = echarts.init(document.getElementById('status'));
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
} else {
proxy.$global.showMsg('暂无数据!');
}
});
}
let getTime = () => {
let year = selectYear.value;
if (!year){
year = new Date().getFullYear();
}
let month = selectMonth.value;
if (!month){
month = new Date().getUTCMonth()+1;
}
if (month <10){
month = '0'+month;
}
let time = year+"-"+month;
return time;
}
let showOrHideDia = (flg) => {
dialogVisible.value = flg
}
// 年度工单统计
let getSummary = () => {
let year = selectYear.value;
if (!year){
year = new Date().getFullYear();
}
let url = "/api-web/bOpsProjectEvaluation/getSummary?projectId="+props.projectId+"&year="+year;
proxy.$http.get(url, {}, function (res) {
if (res && res.success && res.object) {
summaryDatas.value = res.object;
} else {
proxy.$global.showMsg('暂无数据!');
}
});
}
let init =() =>{
getLabel();
getMonth();
getSelectYearAndMonth();
getSummary();
workOrderSummary();
workOrderClosedAvg();
unClosedTop10();
}
// 监听编辑状态
Vue.watch(() => props.treeNode, (newValue, oldVlaue) => {
init();
});
// 挂载完
Vue.onMounted(() => {
init();
})
return {
width,
height,
dlgHeight,
fullWidth,
title,
dialogVisible,
showOrHideDia,
labels,
months,
yearSel,
monthSel,
getSummary,
workOrderClosedAvg,
summaryDatas,
selectYearAndMonth,
getSelectYearAndMonth,
unClosedTop10,
yearType,
monthType
}
}
}
... ...
... ... @@ -18,6 +18,10 @@ export default {
'COLLECT_MATERIAL': Vue.defineAsyncComponent(
() => myImport('components/page/operationMaintenance/zl/index')
),
// 乙方运维评估
'COLLECT_EVALUATION': Vue.defineAsyncComponent(
() => myImport('components/page/operationMaintenance/pg/index')
),
//文档
// 个人保密协议(THREE_PERSONAGE_NDA)
// 月度总结 THREE_MONTHLY_SUMMARY
... ... @@ -113,7 +117,6 @@ export default {
}
let handleNodeClick = (data) => {
let comName = data.map.nodeType.view.code;
let code = data.map.nodeType.code;
if (comName == 'DOCUMENT') {
... ...