Authored by 王涛

Merge branch 'master-joke' into 'master'

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

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

See merge request !1107
  1 +<div style="padding: 0px 10px 0px 0px;">
  2 + <el-row :gutter="5" style="padding: 0px 5px 0px 0px;">
  3 + <el-button-group>
  4 + <el-button v-for="(item,index) in labels" :type="yearType==index?'primary':''"
  5 + style="display: inline-block;margin: 0px" @click="yearSel(item,index)"
  6 + :label="label">{{item.name}}
  7 + </el-button>
  8 + </el-button-group>
  9 + </el-row>
  10 + <el-row :gutter="5">
  11 + <el-col :span="24" style="border: #eeeeee 1px solid">
  12 + <el-row :gutter="5">
  13 + <el-col :span="24">
  14 + <el-descriptions
  15 + style="height: 60px;margin: 0px;padding-top: 20px;border-top: #eeeeee 1px solid;border-bottom: #eeeeee 1px solid"
  16 + :contentStyle="rowCenter" :labelStyle="rowCenter" title="" :column="4"
  17 + :data="summaryDatas">
  18 + <el-descriptions-item label="年度工单总数:">{{summaryDatas.total}}个</el-descriptions-item>
  19 + <el-descriptions-item label="年度已关闭工单总数:">{{summaryDatas.closedTotal}}个
  20 + </el-descriptions-item>
  21 + <el-descriptions-item label="年度已关闭工单平均用时:">{{summaryDatas.avgTotal}}天
  22 + </el-descriptions-item>
  23 + <el-descriptions-item label="年度已关闭工单省局环节平均用时:">{{summaryDatas.avgSjTotal}}天
  24 + </el-descriptions-item>
  25 + </el-descriptions>
  26 + </el-col>
  27 + </el-row>
  28 + <el-row :gutter="5">
  29 + <el-col :span="6">
  30 + <label style="float: left;line-height: 50px;padding-left: 10px"><span class="selYearAndMonth"
  31 + >{{selectYearAndMonth}}</span>工单分析图</label>
  32 + </el-col>
  33 + <el-col :span="18">
  34 + <div style="display: inline-block;float: right;margin-right: 5px">
  35 + 月份筛选:
  36 + <el-button-group>
  37 + <el-button v-for="(item,index) in months" :type="monthType==index?'primary':''"
  38 + style="display: inline-block;margin: 5px 0px"
  39 + @click="monthSel(item,index)" :label="label">{{item.name}}
  40 + </el-button>
  41 + </el-button-group>
  42 +
  43 + </div>
  44 + </el-col>
  45 + <el-col :span="24" style="margin: 0px 30px 0px 0px">
  46 + <el-row :gutter="5">
  47 + <!--受理环节-->
  48 + <el-col :span="9">
  49 + <div id="status"
  50 + :style="{'height' : height + 'px','border':'#eeeeee 1px solid','margin':'5px'}"></div>
  51 + </el-col>
  52 + <!--受理环节-->
  53 + <el-col :span="15">
  54 + <div id="tache"
  55 + :style="{'height' : height + 'px','border':'#eeeeee 1px solid','margin':'5px 5px 5px 0px'}"></div>
  56 + </el-col>
  57 + </el-row>
  58 + <el-row :gutter="5">
  59 + <el-col :span="24">
  60 + <div id="top10"
  61 + :style="{'height' : height + 'px','border':'#eeeeee 1px solid','margin':'5px'}"></div>
  62 + </el-col>
  63 + </el-row>
  64 + </el-col>
  65 +
  66 + </el-row>
  67 + </el-col>
  68 + </el-row>
  69 + <!--弹框,展示各环节分析echarts-->
  70 + <cm-dialog title="分析" width="80%" :showDialogVisible="dialogVisible" :showFooter="false"
  71 + @hidedialog="showOrHideDia" :showOkBtn="false">
  72 + <el-row>
  73 + <!--受理环节-->
  74 + <el-col :span="12">
  75 + <div id="slSummary" style="height: 300px;margin: 10px;border: #eeeeee 1px solid"
  76 + class="diaEcharts"></div>
  77 + </el-col>
  78 + <!--分析环节-->
  79 + <el-col :span="12">
  80 + <div id="fxSummary" style="height: 300px;margin: 10px;border: #eeeeee 1px solid"
  81 + class="diaEcharts"></div>
  82 + </el-col>
  83 + </el-row>
  84 + <el-row>
  85 + <!--审批环节-->
  86 + <el-col :span="12">
  87 + <div id="spSummary" style="height: 300px;margin: 10px;border: #eeeeee 1px solid"
  88 + class="diaEcharts"></div>
  89 + </el-col>
  90 + <!--修改环节-->
  91 + <el-col :span="12">
  92 + <div id="xgSummary" style="height: 300px;margin: 10px;border: #eeeeee 1px solid"
  93 + class="diaEcharts"></div>
  94 + </el-col>
  95 + </el-row>
  96 + </cm-dialog>
  97 +</div>
  1 +export default {
  2 + name: 'projectPGIndex',
  3 + template: '',
  4 + components: {},
  5 + data() {
  6 + return {
  7 + rowCenter:{
  8 + "text-align":"center"
  9 + }
  10 + }
  11 + },
  12 + props: {
  13 + treeNode: {
  14 + type: Object,
  15 + default: {}
  16 + },
  17 + parentNode: {
  18 + type: Object,
  19 + default: {}
  20 + },
  21 + projectId: {
  22 + type: String,
  23 + default: ''
  24 + },
  25 + key: {
  26 + type: String,
  27 + default: ''
  28 + },
  29 + },
  30 + setup(props, {attrs, slots, emit}) {
  31 + let height = Vue.ref((window.innerHeight - 200)/2);
  32 + let dlgHeight = Vue.ref((window.innerHeight - 160)/3)
  33 + let width = Vue.ref(window.innerWidth * 0.6);
  34 + let fullWidth = Vue.ref(window.innerWidth - 200);
  35 + let dialogVisible = Vue.ref(false);
  36 + let title = Vue.ref('');
  37 + let labels = Vue.ref([]);
  38 + let months = Vue.ref([]);
  39 + let summaryDatas = Vue.ref({})
  40 + let selectMonth = Vue.ref('');
  41 + let selectYear = Vue.ref('');
  42 + let selectYearAndMonth = Vue.ref('');
  43 + let yearType = Vue.ref(0);
  44 + let monthType = Vue.ref(0);
  45 +
  46 +
  47 + const {proxy} = Vue.getCurrentInstance();
  48 +
  49 + let yearSel = (item,index) => {
  50 + yearType.value = index
  51 + selectYear.value = item.value;
  52 + selectYearAndMonth.value = selectYear.value + '年'+ selectMonth.value + '月';
  53 + getSummary();
  54 + workOrderSummary();
  55 + workOrderClosedAvg();
  56 + unClosedTop10();
  57 + }
  58 +
  59 + let monthSel = (item,index) =>{
  60 + monthType.value = index
  61 + selectMonth.value = item.value;
  62 + selectYearAndMonth.value = selectYear.value + '年'+ selectMonth.value + '月';
  63 + workOrderSummary();
  64 + workOrderClosedAvg();
  65 + unClosedTop10();
  66 + }
  67 +
  68 + let getLabel = () => {
  69 + let years = [];
  70 + let nowYear = new Date().getFullYear();
  71 + selectYear.value = nowYear+'';
  72 + for (let i = nowYear; i >= 2022; i--) {
  73 + let yearObj = {};
  74 + yearObj.value = i+'';
  75 + yearObj.name = i+'年度';
  76 + years.push(yearObj);
  77 + }
  78 + labels.value = years;
  79 + }
  80 +
  81 + let getMonth = () => {
  82 + let nowMonth = new Date().getUTCMonth()+1;
  83 + selectMonth.value = nowMonth;
  84 + let monthArr = [];
  85 + for (let i = 1; i <= 12 ; i++) {
  86 + let monthObj = {};
  87 + monthObj.value = i+'';
  88 + //设置默认月份
  89 + if (nowMonth == i){
  90 + monthType.value = i-1;
  91 + }
  92 + monthObj.name = (i)+'月';
  93 + monthArr.push(monthObj);
  94 + }
  95 + months.value = monthArr;
  96 + }
  97 +
  98 +
  99 + let getSelectYearAndMonth = () => {
  100 + let year = new Date().getFullYear();
  101 + let month = new Date().getUTCMonth()+1;
  102 + selectYearAndMonth.value = year+ '年'+month+'月'
  103 + }
  104 +
  105 + // 已关闭事件审批环节平均用时柱状图
  106 + let workOrderClosedAvg = () => {
  107 + let time = getTime();
  108 + let url = "/api-web/bOpsProjectEvaluation/getWorkOrderClosedAvgEcharts?projectId="+props.projectId+"&time="+time;
  109 + proxy.$http.get(url, {}, function (res) {
  110 + if (res && res.success && res.data) {
  111 + let xDatas = [];
  112 + let yDatas = [];
  113 + res.data.forEach(item => {
  114 + xDatas.push(item.KEY);
  115 + yDatas.push(item.NUM);
  116 + })
  117 + // 基于准备好的dom,初始化echarts实例
  118 + var myChart = echarts.init(document.getElementById('tache'));
  119 +
  120 + // 指定图表的配置项和数据
  121 + var option = {
  122 + toolbox: {
  123 + show : true,
  124 + feature : {
  125 + //敲黑板,重点!!!
  126 + myTool2:{//自定义按钮 danielinbiti,这里增加,selfbuttons可以随便取名字
  127 + show:true,//是否显示
  128 + title:'分析', //鼠标移动上去显示的文字
  129 + 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', //图标
  130 + onclick:function() {//点击事件,这里的option1是chart的option信息
  131 + dialogEchartsLoad();
  132 + }
  133 + }
  134 + }
  135 + },
  136 + grid:{
  137 + right: '10%'
  138 + },
  139 + title: {
  140 + text: '已关闭事件审批环节平均用时',
  141 + textStyle:{
  142 + //文字颜色
  143 + //字体风格,'normal','italic','oblique'
  144 + fontStyle:'normal',
  145 + //字体粗细 'normal','bold','bolder','lighter',100 | 200 | 300 | 400...
  146 + fontWeight:'bold',
  147 + //字体系列
  148 + fontFamily:'sans-serif',
  149 + //字体大小
  150 + fontSize:14
  151 + }
  152 + },
  153 + xAxis: {
  154 + data: xDatas,
  155 + },
  156 + yAxis: {
  157 + name: "单位(天)",
  158 + },
  159 + tooltip: { // 鼠标悬浮提示框显示 X和Y 轴数据
  160 + backgroundColor: 'rgba(32, 33, 36,.7)',
  161 + borderColor: 'rgba(32, 33, 36,0.20)',
  162 + borderWidth: 1,
  163 + textStyle: { // 文字提示样式
  164 + color: '#fff',
  165 + fontSize: '12'
  166 + },
  167 + },
  168 + series: [
  169 + {
  170 + type: 'bar',
  171 + barWidth: '50%',
  172 + itemStyle: {
  173 + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  174 + { offset: 0, color: '#c0fbe3' },
  175 + { offset: 0.5, color: '#aef8d4' },
  176 + { offset: 1, color: '#aef8d4' }
  177 + ])
  178 + },
  179 + data: yDatas
  180 + }
  181 + ]
  182 + };
  183 + // 使用刚指定的配置项和数据显示图表。
  184 + myChart.setOption(option);
  185 + }
  186 + }, function () {
  187 + proxy.$global.showMsg('没有查询到记录!', 'warning');
  188 + });
  189 + }
  190 +
  191 + let dialogEchartsLoad = () => {
  192 + showOrHideDia(true);
  193 + let time = getTime();
  194 + let url = "/api-web/bOpsProjectEvaluation/getWorkOrderClosedAvgDlgEcharts?projectId="+props.projectId+"&time="+time;
  195 + proxy.$http.get(url, {}, function (res) {
  196 + if (res && res.success && res.object) {
  197 + let slSummary = res.object.slSummary;
  198 + let fxSummary = res.object.fxSummary;
  199 + let spSummary = res.object.spSummary;
  200 + let xgSummary = res.object.xgSummary;
  201 + setOption(slSummary,'slSummary','受理环节');
  202 + setOption(fxSummary,'fxSummary','分析环节');
  203 + setOption(spSummary,'spSummary','审批环节');
  204 + setOption(xgSummary,'xgSummary','修改环节');
  205 + }
  206 + }, function () {
  207 + proxy.$global.showMsg('没有查询到记录!', 'warning');
  208 + });
  209 + }
  210 +
  211 + let setOption = (summaryData,id,name) => {
  212 + let arr = [];
  213 + summaryData.forEach(item => {
  214 + arr.push({value: item.SERID, name: item.TIME})
  215 + })
  216 + // 指定图表的配置项和数据
  217 + var option = {
  218 + title: {
  219 + text: name,
  220 + left: 'center',
  221 + top: 'bottom',
  222 + textStyle:{
  223 + //文字颜色
  224 + //字体风格,'normal','italic','oblique'
  225 + fontStyle:'normal',
  226 + //字体粗细 'normal','bold','bolder','lighter',100 | 200 | 300 | 400...
  227 + fontWeight:'bold',
  228 + //字体系列
  229 + fontFamily:'sans-serif',
  230 + //字体大小
  231 + fontSize:14,
  232 + }
  233 + },
  234 + tooltip: {
  235 + triggeer: 'item',
  236 + formatter: '{b} : {c} ({d}%)'
  237 + },
  238 + series: [
  239 + {
  240 + name: '',
  241 + type: 'pie', // 设置图表类型为饼图
  242 +
  243 + data: arr,
  244 + label: {
  245 + normal: {
  246 + show: true,
  247 + formatter: '{b}:{c}({d}%)'
  248 + },
  249 + labelLine: {show: true}
  250 + },
  251 + }
  252 + ],
  253 + };
  254 + // 让 指定id 的 div 的_echarts_instance_属性值 为 空状态
  255 + document.getElementById(id).removeAttribute('_echarts_instance_');
  256 + var myChart = echarts.init(document.getElementById(id));
  257 + // 使用刚指定的配置项和数据显示图表。
  258 + myChart.setOption(option);
  259 + }
  260 +
  261 +
  262 + // 未处理完成时长Top10工单柱状图
  263 + let unClosedTop10 = () => {
  264 + let time = getTime();
  265 + let url = "/api-web/bOpsProjectEvaluation/getWorkOrderUnClosedTop10?projectId="+props.projectId+"&time="+time;
  266 + proxy.$http.get(url, {}, function (res) {
  267 + if (res && res.success && res.data) {
  268 + let xDatas = [];
  269 + let yDatas = [];
  270 + res.data.forEach(item => {
  271 + xDatas.push(item.DIVID);
  272 + yDatas.push(item.DAYS);
  273 + })
  274 + // 基于准备好的dom,初始化echarts实例
  275 + var myChart = echarts.init(document.getElementById('top10'));
  276 +
  277 + // 指定图表的配置项和数据
  278 + var option = {
  279 + color: ['#6ec0cf'],
  280 + title: {
  281 + text: '未处理完成时长Top10工单',
  282 + textStyle:{
  283 + //文字颜色
  284 + //字体风格,'normal','italic','oblique'
  285 + fontStyle:'normal',
  286 + //字体粗细 'normal','bold','bolder','lighter',100 | 200 | 300 | 400...
  287 + fontWeight:'bold',
  288 + //字体系列
  289 + fontFamily:'sans-serif',
  290 + //字体大小
  291 + fontSize:14
  292 + }
  293 + },
  294 + xAxis: {
  295 + data: xDatas,
  296 + },
  297 + yAxis: {
  298 + name: "单位(天)",
  299 + },
  300 + tooltip: { // 鼠标悬浮提示框显示 X和Y 轴数据
  301 + backgroundColor: 'rgba(32, 33, 36,.7)',
  302 + borderColor: 'rgba(32, 33, 36,0.20)',
  303 + borderWidth: 1,
  304 + textStyle: { // 文字提示样式
  305 + color: '#fff',
  306 + fontSize: '12'
  307 + },
  308 + formatter: '{b} 工单时长 : {c} 天'
  309 + },
  310 + series: [
  311 + {
  312 + type: 'bar',
  313 + barWidth: '50%',
  314 + data: yDatas
  315 + }
  316 + ]
  317 + };
  318 + // 使用刚指定的配置项和数据显示图表。
  319 + myChart.setOption(option);
  320 + }
  321 + }, function () {
  322 + proxy.$global.showMsg('没有查询到记录!', 'warning');
  323 + });
  324 + }
  325 +
  326 + // 各状态工单量占比饼状图
  327 + let workOrderSummary = () => {
  328 + let time = getTime();
  329 + let url = "/api-web/bOpsProjectEvaluation/getWorkOrderAnalyseEcharts?projectId="+props.projectId+"&time="+time;
  330 + proxy.$http.get(url, {}, function (res) {
  331 + if (res && res.success && res.data) {
  332 + let arr = [];
  333 + res.data.forEach(item => {
  334 + arr.push({value: item.COUNT, name: item.WORKFLOWSTATUS2})
  335 + })
  336 + // 指定图表的配置项和数据
  337 + var option = {
  338 + color: ['#5979f6', '#79d6a6'],
  339 + title: {
  340 + text: '各状态工单量占比',
  341 + textStyle:{
  342 + //文字颜色
  343 + //字体风格,'normal','italic','oblique'
  344 + fontStyle:'normal',
  345 + //字体粗细 'normal','bold','bolder','lighter',100 | 200 | 300 | 400...
  346 + fontWeight:'bold',
  347 + //字体系列
  348 + fontFamily:'sans-serif',
  349 + //字体大小
  350 + fontSize:14
  351 + }
  352 + },
  353 + tooltip: {
  354 + triggeer: 'item',
  355 + formatter: '{b} : {c} ({d}%)'
  356 + },
  357 + series: [
  358 + {
  359 + name: '各状态工单量占比',
  360 + type: 'pie', // 设置图表类型为饼图
  361 + radius: '60%', // 饼图的半径,外半径为可视区尺寸(容器高宽中较小一项)的 55% 长度。
  362 + center: ["50%", "50%"],
  363 + data: arr,
  364 + label: {
  365 + normal: {
  366 + show: true,
  367 + formatter: '{b}:{c}({d}%)'
  368 + },
  369 + labelLine: {show: true}
  370 + },
  371 + }
  372 + ],
  373 + };
  374 +
  375 + var myChart = echarts.init(document.getElementById('status'));
  376 + // 使用刚指定的配置项和数据显示图表。
  377 + myChart.setOption(option);
  378 + } else {
  379 + proxy.$global.showMsg('暂无数据!');
  380 + }
  381 + });
  382 + }
  383 +
  384 + let getTime = () => {
  385 + let year = selectYear.value;
  386 + if (!year){
  387 + year = new Date().getFullYear();
  388 + }
  389 + let month = selectMonth.value;
  390 + if (!month){
  391 + month = new Date().getUTCMonth()+1;
  392 + }
  393 + if (month <10){
  394 + month = '0'+month;
  395 + }
  396 + let time = year+"-"+month;
  397 + return time;
  398 + }
  399 +
  400 +
  401 +
  402 + let showOrHideDia = (flg) => {
  403 + dialogVisible.value = flg
  404 + }
  405 +
  406 + // 年度工单统计
  407 + let getSummary = () => {
  408 + let year = selectYear.value;
  409 + if (!year){
  410 + year = new Date().getFullYear();
  411 + }
  412 + let url = "/api-web/bOpsProjectEvaluation/getSummary?projectId="+props.projectId+"&year="+year;
  413 + proxy.$http.get(url, {}, function (res) {
  414 + if (res && res.success && res.object) {
  415 + summaryDatas.value = res.object;
  416 + } else {
  417 + proxy.$global.showMsg('暂无数据!');
  418 + }
  419 + });
  420 + }
  421 +
  422 + let init =() =>{
  423 + getLabel();
  424 + getMonth();
  425 + getSelectYearAndMonth();
  426 + getSummary();
  427 + workOrderSummary();
  428 + workOrderClosedAvg();
  429 + unClosedTop10();
  430 + }
  431 +
  432 + // 监听编辑状态
  433 + Vue.watch(() => props.treeNode, (newValue, oldVlaue) => {
  434 + init();
  435 + });
  436 +
  437 + // 挂载完
  438 + Vue.onMounted(() => {
  439 + init();
  440 + })
  441 +
  442 +
  443 + return {
  444 + width,
  445 + height,
  446 + dlgHeight,
  447 + fullWidth,
  448 + title,
  449 + dialogVisible,
  450 + showOrHideDia,
  451 + labels,
  452 + months,
  453 + yearSel,
  454 + monthSel,
  455 + getSummary,
  456 + workOrderClosedAvg,
  457 + summaryDatas,
  458 + selectYearAndMonth,
  459 + getSelectYearAndMonth,
  460 + unClosedTop10,
  461 + yearType,
  462 + monthType
  463 + }
  464 + }
  465 +}
@@ -18,6 +18,10 @@ export default { @@ -18,6 +18,10 @@ export default {
18 'COLLECT_MATERIAL': Vue.defineAsyncComponent( 18 'COLLECT_MATERIAL': Vue.defineAsyncComponent(
19 () => myImport('components/page/operationMaintenance/zl/index') 19 () => myImport('components/page/operationMaintenance/zl/index')
20 ), 20 ),
  21 + // 乙方运维评估
  22 + 'COLLECT_EVALUATION': Vue.defineAsyncComponent(
  23 + () => myImport('components/page/operationMaintenance/pg/index')
  24 + ),
21 //文档 25 //文档
22 // 个人保密协议(THREE_PERSONAGE_NDA) 26 // 个人保密协议(THREE_PERSONAGE_NDA)
23 // 月度总结 THREE_MONTHLY_SUMMARY 27 // 月度总结 THREE_MONTHLY_SUMMARY
@@ -113,7 +117,6 @@ export default { @@ -113,7 +117,6 @@ export default {
113 } 117 }
114 118
115 let handleNodeClick = (data) => { 119 let handleNodeClick = (data) => {
116 -  
117 let comName = data.map.nodeType.view.code; 120 let comName = data.map.nodeType.view.code;
118 let code = data.map.nodeType.code; 121 let code = data.map.nodeType.code;
119 if (comName == 'DOCUMENT') { 122 if (comName == 'DOCUMENT') {