-
281src/views/xm/core/xmTestPlan/rpt/CompsCard.vue
-
304src/views/xm/core/xmTestPlan/rpt/CompsSet.vue
-
299src/views/xm/core/xmTestPlan/rpt/biz/productWorkItemDayList.vue
-
334src/views/xm/core/xmTestPlan/rpt/biz/question.vue
-
259src/views/xm/core/xmTestPlan/rpt/biz/questionAgeDist.vue
-
48src/views/xm/core/xmTestPlan/rpt/biz/questionAskUserSort.vue
-
334src/views/xm/core/xmTestPlan/rpt/biz/questionAttDist.vue
-
47src/views/xm/core/xmTestPlan/rpt/biz/questionBugReasonDist.vue
-
48src/views/xm/core/xmTestPlan/rpt/biz/questionBugSeverityDist.vue
-
48src/views/xm/core/xmTestPlan/rpt/biz/questionBugStatusDist.vue
-
48src/views/xm/core/xmTestPlan/rpt/biz/questionBugTypeDist.vue
-
48src/views/xm/core/xmTestPlan/rpt/biz/questionFuncSort.vue
-
48src/views/xm/core/xmTestPlan/rpt/biz/questionHandlerUserSort.vue
-
48src/views/xm/core/xmTestPlan/rpt/biz/questionMenuSort.vue
-
48src/views/xm/core/xmTestPlan/rpt/biz/questionPriorityDist.vue
-
48src/views/xm/core/xmTestPlan/rpt/biz/questionRepRateDist.vue
-
275src/views/xm/core/xmTestPlan/rpt/biz/questionRetestDist.vue
-
48src/views/xm/core/xmTestPlan/rpt/biz/questionSolutionDist.vue
-
282src/views/xm/core/xmTestPlan/rpt/biz/questionSort.vue
-
203src/views/xm/core/xmTestPlan/rpt/biz/testCaseToPlanCalc.vue
-
188src/views/xm/core/xmTestPlan/rpt/biz/testDayTimesCalc.vue
-
222src/views/xm/core/xmTestPlan/rpt/biz/testPlanCaseExecStatusDist.vue
-
249src/views/xm/core/xmTestPlan/rpt/biz/testPlanCaseUserDist.vue
-
10src/views/xm/core/xmTestPlan/rpt/common.scss
-
BINsrc/views/xm/core/xmTestPlan/rpt/images/area-stack.png
-
BINsrc/views/xm/core/xmTestPlan/rpt/images/bar.png
-
BINsrc/views/xm/core/xmTestPlan/rpt/images/dataset-link.png
-
BINsrc/views/xm/core/xmTestPlan/rpt/images/line-stack.png
-
BINsrc/views/xm/core/xmTestPlan/rpt/images/pie-simple.png
-
BINsrc/views/xm/core/xmTestPlan/rpt/images/ranjintu.png
-
98src/views/xm/core/xmTestPlan/rpt/index.scss
-
58src/views/xm/core/xmTestPlan/rpt/index.vue
-
1src/views/xm/rpt/CompsSet.vue
-
1src/views/xm/rpt/comps.js
-
407src/views/xm/rpt/testPlan/testPlanRptOverview.vue
@ -1,281 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row class="page-center border" v-if="printVisible==false"> |
|||
<el-col :span="6" :style="{height:maxTableHeight+'px',overflow:'auto'}"> |
|||
<comps-set v-if="rptConfigVisible" :comp-ids="compIds" @row-click="onCompSelect"></comps-set> |
|||
</el-col> |
|||
<el-col :span="18" :style="{height:maxTableHeight+'px',overflow:'auto'}" ref="table" class="border"> |
|||
<div> |
|||
<div class="empty" v-if="compCfgList.length == 0" > |
|||
<el-empty description="暂未选择模块"></el-empty> |
|||
</div> |
|||
<div v-else> |
|||
<grid-layout |
|||
:layout.sync="compCfgList" |
|||
:col-num="layoutColNum" |
|||
:row-height="120" |
|||
:is-draggable="true" |
|||
:is-resizable="true" |
|||
:is-mirrored="false" |
|||
:vertical-compact="true" |
|||
:margin="[10, 10]" |
|||
:use-css-transforms="true" |
|||
> |
|||
<grid-item |
|||
v-for="(item,index) in compCfgList" |
|||
:x="item.x" |
|||
:y="item.y" |
|||
:w="item.w" |
|||
:h="item.h" |
|||
:i="item.i" |
|||
:key="index" @resize="sizeAutoChange(item)"> |
|||
<component :is="item.compId" :xm-test-plan="xmTestPlan" :comp-cfg="item" :ref="item.id" @delete="doDelete" :id="item.id+'-id'"></component> |
|||
</grid-item> |
|||
</grid-layout> |
|||
</div> |
|||
</div> |
|||
</el-col> |
|||
</el-row> |
|||
<el-row v-if="printVisible" class="page-center border" style="width:1000px;"> |
|||
<el-row> |
|||
<span style="float:right;"><el-button @click="printVisible=false">取消打印</el-button> <el-button v-print="'#printBody'">打印</el-button></span> |
|||
</el-row> |
|||
<el-row id="printBody"> |
|||
<el-row v-for="(item,index) in compCfgList" :key="index"> |
|||
<component :is="item.compId" :xm-test-plan="xmTestPlan" :comp-cfg="item" :ref="item.id" @delete="doDelete"></component> |
|||
</el-row> |
|||
</el-row> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import util from '@/common/js/util';//全局公共库 |
|||
import seq from '@/common/js/sequence';//全局公共库 |
|||
import VueGridLayout from 'vue-grid-layout'; |
|||
import { mapGetters } from 'vuex' |
|||
import XmTestPlanMng from '@/views/xm/core/xmTestPlan/XmTestPlanMng' |
|||
import CompsSet from '@/views/xm/core/xmTestPlan/rpt/CompsSet' |
|||
import XmQuestionAgeDist from '@/views/xm/core/xmTestPlan/rpt/biz/questionAgeDist' |
|||
import xmQuestionAttDist from '@/views/xm/core/xmTestPlan/rpt/biz/questionAttDist' |
|||
import xmQuestionRetestDist from '@/views/xm/core/xmTestPlan/rpt/biz/questionRetestDist' |
|||
import xmQuestionHandlerUserSort from '@/views/xm/core/xmTestPlan/rpt/biz/questionHandlerUserSort' |
|||
import xmQuestionAskUserSort from '@/views/xm/core/xmTestPlan/rpt/biz/questionAskUserSort' |
|||
import xmQuestionMenuSort from '@/views/xm/core/xmTestPlan/rpt/biz/questionMenuSort' |
|||
import xmQuestionFuncSort from '@/views/xm/core/xmTestPlan/rpt/biz/questionFuncSort' |
|||
import xmTestPlanCaseExecStatusDist from '@/views/xm/core/xmTestPlan/rpt/biz/testPlanCaseExecStatusDist' |
|||
import xmTestPlanCaseUserDist from '@/views/xm/core/xmTestPlan/rpt/biz/testPlanCaseUserDist' |
|||
import xmTestCaseToPlanCalc from '@/views/xm/core/xmTestPlan/rpt/biz/testCaseToPlanCalc' |
|||
import xmTestDayTimesCalc from '@/views/xm/core/xmTestPlan/rpt/biz/testDayTimesCalc' |
|||
|
|||
import xmTestRptOverview from '@/views/xm/core/xmTestPlan/xmTestRptOverview' |
|||
|
|||
import { initDicts,listXmRptConfig, delXmRptConfig,editXmRptConfig,addXmRptConfig,batchDelXmRptConfig,editSomeFieldsXmRptConfig } from '@/api/xm/core/xmRptConfig'; |
|||
|
|||
export default { |
|||
components: { |
|||
GridLayout: VueGridLayout.GridLayout, |
|||
GridItem: VueGridLayout.GridItem, |
|||
XmTestPlanMng, |
|||
XmQuestionAgeDist, |
|||
xmQuestionAttDist, |
|||
xmQuestionHandlerUserSort,xmQuestionAskUserSort,xmQuestionMenuSort,xmQuestionFuncSort, |
|||
xmTestPlanCaseExecStatusDist, |
|||
xmTestPlanCaseUserDist, |
|||
CompsSet, |
|||
xmTestRptOverview, |
|||
xmQuestionRetestDist, |
|||
xmTestCaseToPlanCalc, |
|||
xmTestDayTimesCalc, |
|||
|
|||
"xmQuestionBugReasonDist":()=>import("./biz/questionBugReasonDist.vue"), |
|||
"xmQuestionBugStatusDist":()=>import("./biz/questionBugStatusDist.vue"), |
|||
"xmQuestionBugTypeDist":()=>import("./biz/questionBugTypeDist.vue"), |
|||
"xmQuestionRepRateDist":()=>import("./biz/questionRepRateDist.vue"), |
|||
"xmQuestionBugSeverityDist":()=>import("./biz/questionBugSeverityDist.vue"), |
|||
"xmQuestionSolutionDist":()=>import("./biz/questionSolutionDist.vue"), |
|||
"xmQuestionPriorityDist":()=>import("./biz/questionPriorityDist.vue"), |
|||
"productWorkItemDayList":()=>import("./biz/productWorkItemDayList.vue"), |
|||
|
|||
}, |
|||
props:['xmTestPlan','rptConfigVisible'], |
|||
computed: { |
|||
...mapGetters(['userInfo']), |
|||
compIds(){ |
|||
return this.compCfgList.map(k=>k.compId) |
|||
}, |
|||
|
|||
}, |
|||
|
|||
watch: { |
|||
xmRptConfig:{ |
|||
handler(){ |
|||
this.initCompCfgList(); |
|||
}, |
|||
deep:true, |
|||
}, |
|||
rptConfigVisible(){ |
|||
if(this.rptConfigVisible==true){ |
|||
this.$nextTick(()=>{ |
|||
this.compCfgList.forEach(k=>{ |
|||
this.sizeAutoChange(k); |
|||
}) |
|||
}) |
|||
|
|||
} |
|||
}, |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
xmRptConfig:null, |
|||
compCfgList:[], |
|||
maxTableHeight:300, |
|||
// 布局位置数据 |
|||
initCompCfg: [ |
|||
|
|||
{ i:0, x: 0, y: 12, w: 12, h: 6, id:'productWorkItemDayList',name:'测试计划总览',compId:'productWorkItemDayList', params:{} }, |
|||
{ i:0, x: 0, y: 12, w: 12, h: 6, id:'xmTestRptOverview',name:'测试计划总览',compId:'xmTestRptOverview', params:{} }, |
|||
{ i: 1, x: 0, y: 12, w: 12, h: 6, id:'xmTestCaseToPlanCalc',name:'用例规划分析', compId:'xmTestCaseToPlanCalc', }, |
|||
{ i: 2, x: 0, y: 12, w: 12, h: 6, id:'xmTestDayTimesCalc',name:'用例每日执行统计', compId:'xmTestDayTimesCalc', }, |
|||
{ i: 3, x: 0, y: 12, w: 12, h: 6, id:'xmTestPlanCaseExecStatusDist',name:'用例执行结果分布', compId:'xmTestPlanCaseExecStatusDist', }, |
|||
{ i: 4, x: 0, y: 12, w: 12, h: 6, id:'xmTestPlanCaseUserDist',name:'用例执行人情况分布', compId:'xmTestPlanCaseUserDist', }, |
|||
{ i:5, x: 0, y: 12, w: 12, h: 6, id:'xmQuestionMenuSort',name:'缺陷需求分布', compId:'xmQuestionMenuSort', }, |
|||
{ i: 6, x: 0, y: 12, w: 12, h: 6, id:'xmQuestionFuncSort',name:'缺陷模块分布', compId:'xmQuestionFuncSort', }, |
|||
{ i: 7, x: 0, y: 12, w: 12, h: 6, id:'xmQuestionBugStatusDist',name:'缺陷状态分布',compId:'xmQuestionBugStatusDist', }, |
|||
{ i:8, x: 0, y: 12, w: 12, h: 6, id:'xmQuestionAgeDist',name:'缺陷年龄分布',compId:'xmQuestionAgeDist', params:{} }, |
|||
{ i:9, x: 0, y: 12, w: 12, h: 6, id:'xmQuestionBugReasonDist',name:'缺陷原因分布',compId:'xmQuestionBugReasonDist', params:{} }, |
|||
{ i:10, x: 0, y: 12, w: 12, h: 6, id:'xmQuestionPriorityDist',name:'缺陷紧急程度分布',compId:'xmQuestionPriorityDist', params:{} }, |
|||
{ i: 11, x: 0, y: 12, w: 12, h: 6, id:'xmQuestionAskUserSort',name:'缺陷提出人排行榜', compId:'xmQuestionAskUserSort', }, |
|||
{ i: 12, x: 0, y: 12, w: 12, h: 6, id:'xmQuestionHandlerUserSort',name:'缺陷负责人排行榜',compId:'xmQuestionHandlerUserSort', }, |
|||
|
|||
|
|||
], |
|||
// 布局列数 |
|||
layoutColNum: 12, |
|||
printVisible:false, |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
initData(){ |
|||
this.getXmRptConfig(); |
|||
}, |
|||
getXmRptConfig(){ |
|||
if(!this.xmTestPlan){ |
|||
return; |
|||
} |
|||
listXmRptConfig({bizId:this.xmTestPlan.id}).then(res=>{ |
|||
this.xmRptConfig=res.data.data[0] |
|||
}) |
|||
}, |
|||
initCompCfgList(){ |
|||
if(this.xmRptConfig && this.xmRptConfig.cfg){ |
|||
var cfgJson=JSON.parse(this.xmRptConfig.cfg) |
|||
this.compCfgList=cfgJson; |
|||
}else{ |
|||
this.compCfgList=JSON.parse(JSON.stringify(this.initCompCfg)) |
|||
} |
|||
}, |
|||
onCompSelect(comp){ |
|||
if(this.compCfgList.some(k=>k.compId==comp.compId)){ |
|||
var compCfg=this.compCfgList.find(k=>k.compId==comp.compId) |
|||
this.$nextTick(()=>{ |
|||
this.scrollToComp(compCfg) |
|||
}) |
|||
return; |
|||
} |
|||
var compCfgListTemp=JSON.parse(JSON.stringify(this.compCfgList)) |
|||
compCfgListTemp.sort((i1,i2)=>{ |
|||
return i2.i-i1.i |
|||
}) |
|||
var maxI=(compCfgListTemp.length>0?(compCfgListTemp[0].i+1):1); |
|||
compCfgListTemp.sort((i1,i2)=>{ |
|||
return i2.y-i1.y |
|||
}) |
|||
var maxY=(compCfgListTemp.length>0?(compCfgListTemp[0].y+6):0); |
|||
var compCfg={i:maxI, x: 0, y: maxY, w: 12, h: 6, compId:comp.compId,name:comp.name,id:comp.compId+seq.sn(),params:{}} |
|||
this.compCfgList.push(compCfg) |
|||
this.$nextTick(()=>{ |
|||
setTimeout(()=>{ |
|||
this.scrollToComp(compCfg) |
|||
},100) |
|||
}) |
|||
|
|||
}, |
|||
scrollToComp(compCfg){ |
|||
var doc=document.getElementById(compCfg.id+'-id') |
|||
if(doc){ |
|||
doc.scrollIntoView(false) |
|||
} |
|||
}, |
|||
submitXmPrtConfig(callback){ |
|||
|
|||
if(this.xmRptConfig==null){ |
|||
var xmRptConfig={name:this.xmTestPlan.name,bizId:this.xmTestPlan.id,cfg:[]} |
|||
var compCfgList=JSON.parse(JSON.stringify(this.compCfgList)) |
|||
compCfgList.forEach(k=>{ |
|||
if(this.$refs[k.id] && this.$refs[k.id][0].$refs && this.$refs[k.id][0].$refs[k.id]){ |
|||
k.params=this.$refs[k.id][0].$refs[k.id].filters |
|||
}else{ |
|||
k.params=this.$refs[k.id][0].filters |
|||
} |
|||
|
|||
}) |
|||
xmRptConfig.cfg=JSON.stringify(compCfgList) |
|||
addXmRptConfig(xmRptConfig).then(res=>{ |
|||
this.xmRptConfig=xmRptConfig; |
|||
callback() |
|||
}) |
|||
}else{ |
|||
var xmRptConfig={id:this.xmRptConfig.id,name:this.xmTestPlan.name,bizId:this.xmTestPlan.id,cfg:[]} |
|||
var compCfgList=JSON.parse(JSON.stringify(this.compCfgList)) |
|||
compCfgList.forEach(k=>{ |
|||
if(this.$refs[k.id] && this.$refs[k.id][0].$refs && this.$refs[k.id][0].$refs[k.id]){ |
|||
k.params=this.$refs[k.id][0].$refs[k.id].filters |
|||
}else{ |
|||
k.params=this.$refs[k.id][0].filters |
|||
} |
|||
}) |
|||
xmRptConfig.cfg=JSON.stringify(compCfgList) |
|||
editXmRptConfig(xmRptConfig).then(res=>{ |
|||
this.xmRptConfig=xmRptConfig; |
|||
callback() |
|||
}) |
|||
} |
|||
}, |
|||
doDelete(compCfg){ |
|||
if(this.rptConfigVisible==false){ |
|||
this.$notify({ position:'bottom-left', showClose:true, message: "当前报告为预览模式,不能删除,请切换为配置报告模式", type: 'error' }); |
|||
return; |
|||
} |
|||
var index=this.compCfgList.findIndex(k=>k.id==compCfg.id) |
|||
if(index>=0){ |
|||
this.compCfgList.splice(index,1) |
|||
} |
|||
}, |
|||
sizeAutoChange(k){ |
|||
if(this.$refs[k.id] && this.$refs[k.id][0].$refs && this.$refs[k.id][0].$refs[k.id]){ |
|||
this.$refs[k.id][0].$refs[k.id].sizeAutoChange(); |
|||
}else{ |
|||
this.$refs[k.id][0].sizeAutoChange(); |
|||
} |
|||
|
|||
} |
|||
|
|||
}, |
|||
|
|||
mounted() { |
|||
this.$nextTick(() => { |
|||
this.initData(); |
|||
this.maxTableHeight = util.calcTableMaxHeight(this.$refs.table.$el) |
|||
}) |
|||
}, |
|||
|
|||
} |
|||
</script> |
|||
|
|||
<style> |
|||
|
|||
</style> |
|||
@ -1,304 +0,0 @@ |
|||
<template> |
|||
<div class="moduleset"> |
|||
<div class="nav"> |
|||
<div class="nav_item" :class="{itemActive: item.isChecked}" v-for="(item, index) in compsCpd" :key="index" @click="selectItem(item, index)"> |
|||
<img :src="item.icon" alt=""> |
|||
<div class="desc"> |
|||
<p>{{item.name}}</p> |
|||
<span> |
|||
{{item.compDesc}} |
|||
</span> |
|||
</div> |
|||
<i v-if="item.isChecked" class="el-icon-success"></i> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import img1 from '../../../../myWork/img/dsp.png' |
|||
import img2 from '../../../../myWork/img/wdrw.png' |
|||
import img3 from '../../../../myWork/img/wdxm.png' |
|||
import img4 from '../../../../myWork/img/wdcp.png' |
|||
|
|||
import pieSimple from './images/pie-simple.png' |
|||
import lineStack from './images/line-stack.png' |
|||
import areaStack from './images/area-stack.png' |
|||
import ranjintu from './images/ranjintu.png' |
|||
import datasetLink from './images/dataset-link.png' |
|||
import bar from './images/bar.png' |
|||
|
|||
import { mapGetters } from 'vuex' |
|||
|
|||
|
|||
export default { |
|||
props: ['compIds' ], |
|||
computed: { |
|||
...mapGetters(['userInfo']), |
|||
compsCpd(){ |
|||
var comps=this.comps; |
|||
if(this.compIds && this.compIds.length>0){ |
|||
comps.forEach(i=>{ |
|||
i.isChecked=this.compIds.some(k=>k==i.compId) |
|||
}) |
|||
} |
|||
return comps; |
|||
} |
|||
}, |
|||
|
|||
watch: { |
|||
|
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
comps: [ |
|||
{ |
|||
compId: 'xmTestRptOverview', |
|||
icon: img1, |
|||
name: '报告总览', |
|||
compDesc: '测试报告总体概览,包括测试总结,测试用例总数、通过率、覆盖率、缺陷数、测试时间等', |
|||
isChecked: false, |
|||
}, |
|||
{ |
|||
compId: 'xmTestCaseToPlanCalc', |
|||
icon: pieSimple, |
|||
name: '用例规划分析', |
|||
compDesc: '统计用例库中规划到测试计划的用例数量情况', |
|||
isChecked: false, |
|||
}, |
|||
{ |
|||
compId: 'xmTestPlanCaseExecStatusDist', |
|||
icon: pieSimple, |
|||
name: '用例执行结果分布', |
|||
compDesc: '按测试用例执行结果统计,通过、失败、忽略、阻塞', |
|||
isChecked: false, |
|||
}, |
|||
{ |
|||
compId: 'xmTestPlanCaseUserDist', |
|||
icon: bar, |
|||
name: '测试用例成员执行结果分布', |
|||
compDesc: '统计测试用例负责人用例执行情况', |
|||
isChecked: false, |
|||
}, |
|||
{ |
|||
compId: 'xmTestDayTimesCalc', |
|||
icon: lineStack, |
|||
name: '每日测试次数统计', |
|||
compDesc: '统计每日执行的测试用例数', |
|||
isChecked: false, |
|||
}, |
|||
{ |
|||
compId: 'xmQuestionFuncSort', |
|||
icon: lineStack, |
|||
name: '缺陷模块分布', |
|||
compDesc: '统计缺陷在各个模块的分布情况', |
|||
isChecked: false, |
|||
}, |
|||
{ |
|||
compId: 'xmQuestionMenuSort', |
|||
icon: lineStack, |
|||
name: '缺陷故事分布', |
|||
compDesc: '统计缺陷在各个用户故事的分布情况', |
|||
isChecked: false, |
|||
}, |
|||
{ |
|||
compId: 'xmQuestionAskUserSort', |
|||
icon: bar, |
|||
name: '缺陷提出人排行榜', |
|||
compDesc: '统计每个提出人的缺陷总数,并按大小进行排序', |
|||
isChecked: false, |
|||
}, |
|||
{ |
|||
compId: 'xmQuestionHandlerUserSort', |
|||
icon: bar, |
|||
name: '缺陷负责人员排行榜', |
|||
compDesc: '统计每个负责人的缺陷总数,并按大小进行排序', |
|||
isChecked: false, |
|||
}, |
|||
{ |
|||
compId: 'xmQuestionRetestDist', |
|||
icon: pieSimple, |
|||
name: '缺陷回归测试分布', |
|||
compDesc: '统计回归测试的次数与缺陷数', |
|||
isChecked: false, |
|||
}, |
|||
{ |
|||
compId: 'xmQuestionAttDist', |
|||
icon: pieSimple, |
|||
name: '缺陷属性分布', |
|||
compDesc: '按缺陷的属性进行统计,多种属性可选择', |
|||
isChecked: false, |
|||
}, |
|||
{ |
|||
compId: 'xmQuestionBugStatusDist', |
|||
icon: pieSimple, |
|||
name: '缺陷状态分布', |
|||
compDesc: '按缺陷状态进行分组统计', |
|||
isChecked: false, |
|||
}, |
|||
{ |
|||
compId: 'xmQuestionBugReasonDist', |
|||
icon: pieSimple, |
|||
name: '缺陷原因分布', |
|||
compDesc: '按缺陷原因进行分组统计', |
|||
isChecked: false, |
|||
}, |
|||
{ |
|||
compId: 'xmQuestionBugTypeDist', |
|||
icon: pieSimple, |
|||
name: '缺陷类型分布', |
|||
compDesc: '按缺陷类型进行分组统计', |
|||
isChecked: false, |
|||
}, |
|||
{ |
|||
compId: 'xmQuestionRepRateDist', |
|||
icon: pieSimple, |
|||
name: '缺陷重现频率分布', |
|||
compDesc: '按缺陷重现频率进行分组统计', |
|||
isChecked: false, |
|||
}, |
|||
{ |
|||
compId: 'xmQuestionSolutionDist', |
|||
icon: pieSimple, |
|||
name: '缺陷解决方案分布', |
|||
compDesc: '按缺陷解决方案进行分组统计', |
|||
isChecked: false, |
|||
}, |
|||
{ |
|||
compId: 'xmQuestionBugSeverityDist', |
|||
icon: pieSimple, |
|||
name: '缺陷紧急程度分布', |
|||
compDesc: '按缺陷紧急程度进行分组统计', |
|||
isChecked: false, |
|||
}, |
|||
{ |
|||
compId: 'xmQuestionPriorityDist', |
|||
icon: pieSimple, |
|||
name: '缺陷优先级分布', |
|||
compDesc: '按缺陷优先级进行分组统计', |
|||
isChecked: false, |
|||
}, |
|||
{ |
|||
compId: 'xmQuestionAgeDist', |
|||
icon: pieSimple, |
|||
name: '缺陷年龄分布', |
|||
compDesc: '统计各个时间长度的缺陷总数', |
|||
isChecked: false, |
|||
} |
|||
], |
|||
|
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
selectItem(item){ |
|||
this.$emit("row-click",item) |
|||
} |
|||
|
|||
|
|||
} |
|||
|
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.moduleset .el-dialog__header { |
|||
padding: 0; |
|||
} |
|||
.moduleset .el-divider--horizontal { |
|||
margin: 0 !important; |
|||
} |
|||
</style> |
|||
|
|||
<style lang="scss" scoped> |
|||
|
|||
|
|||
.moduleset { |
|||
.dialog-title { |
|||
font-size: 22px; |
|||
font-weight: bold; |
|||
color: #7D7D7D; |
|||
height: 68px; |
|||
p { |
|||
line-height: 68px; |
|||
margin-left: 28px; |
|||
} |
|||
} |
|||
.toolBox { |
|||
display: flex; |
|||
flex-direction: column; |
|||
.selectItem { |
|||
display: flex; |
|||
flex-direction: row; |
|||
height: 70px; |
|||
.item { |
|||
display: flex; |
|||
flex-direction: row; |
|||
margin-right: 120px; |
|||
cursor: pointer; |
|||
margin: 25px 50px 0 20px; |
|||
img { |
|||
width: 45px; |
|||
height: 45px; |
|||
} |
|||
span { |
|||
margin-left: 8px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.nav { |
|||
overflow: auto; |
|||
display:flex; |
|||
align-items:center; |
|||
justify-content: space-between; |
|||
flex-wrap:wrap; |
|||
padding-right: 5px; |
|||
.nav_item { |
|||
height: 100px; |
|||
padding:2px; |
|||
display: flex; |
|||
flex-direction: row; |
|||
border: 2px solid #EDF0F9; |
|||
box-shadow: 0px 3px 4px 0px rgba(186, 184, 184, 0.1); |
|||
border-radius: 8px; |
|||
align-items: center; |
|||
position: relative; |
|||
cursor: pointer; |
|||
margin-top: 10px; |
|||
width:100%; |
|||
img { |
|||
object-fit:cover; |
|||
max-width: 25%; |
|||
max-height: 80%; |
|||
padding: 2px; |
|||
} |
|||
p { |
|||
font-size: 18px; |
|||
font-weight: bold; |
|||
color: #7D7D7D; |
|||
margin-bottom: 10px; |
|||
} |
|||
span { |
|||
font-size: 14px; |
|||
color: #7D7D7D; |
|||
line-height: 16px; |
|||
} |
|||
i { |
|||
position: absolute; |
|||
top: 10px; |
|||
right: 10px; |
|||
font-size: 30px; |
|||
color: #90B1F4; |
|||
} |
|||
} |
|||
.itemActive { |
|||
border: 2px solid #90B1F4; |
|||
box-shadow: 0px 3px 4px 0px rgba(186, 184, 184, 0.1); |
|||
} |
|||
} |
|||
} |
|||
|
|||
</style> |
|||
@ -1,299 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
|
|||
<el-row :gutter="5" > |
|||
<el-col :span="18"> |
|||
<div> |
|||
<div class="echart-box" id="productWorkItemDayList" :style="{width:'100%',height:(maxTableHeight>600?600:maxTableHeight)+'px',overflow: 'hidden'}"></div> |
|||
</div> |
|||
</el-col> |
|||
<el-col :span="6" class="border"> |
|||
<el-form :model="filters" class="padding" :style="{width:'100%',maxHeight:maxTableHeight+'px',overflow: 'auto'}" ref="filtersRef"> |
|||
|
|||
<el-form-item label="归属产品" > |
|||
<xm-product-select v-if="!xmProductCpd || !xmProductCpd.id" ref="xmProductSelect" style="display:inline;" :auto-select="false" :link-project-id="xmProject?xmProject.id:null" @row-click="onProductSelected" :iterationId="xmIteration?xmIteration.id:null" @clear="onProductClear"></xm-product-select> |
|||
<span v-else>{{xmProductCpd.id}} <span v-if="xmProductCpd.productName"><br/>{{ xmProductCpd.productName }} </span> </span> |
|||
</el-form-item> |
|||
<el-form-item label="日期区间"> |
|||
<br> |
|||
<mdp-date-range v-model="filters" value-format="yyyy-MM-dd" start-key="startBizDate" end-key="endBizDate"></mdp-date-range> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<el-button type="primary" icon="el-icon-search" @click="listXmProductStateHis">查询</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-col> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '@/common/js/util';//全局公共库 |
|||
import { initSimpleDicts } from '@/api/mdp/meta/item';//下拉框数据查询 |
|||
import { mapGetters } from 'vuex' |
|||
|
|||
import XmProductSelect from '@/views/xm/core/components/XmProductSelect';//新增界面 |
|||
import { listXmProductStateHis } from '@/api/xm/core/xmProductStateHis'; |
|||
export default { |
|||
|
|||
components: { |
|||
XmProductSelect, |
|||
}, |
|||
props:['xmProduct','xmProject'], |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo','roles' |
|||
]), |
|||
dataSetCpd(){ |
|||
return [ |
|||
['日期',...this.xmProductStateHiss.map(i=>i.bizDate)], |
|||
['未关故事',...this.xmProductStateHiss.map(i=>i.menuCnt-i.menuCloseCnt)], |
|||
['已关故事',...this.xmProductStateHiss.map(i=>i.menuCloseCnt)], |
|||
['未关任务',...this.xmProductStateHiss.map(i=>i.taskCnt-i.taskCloseCnt)], |
|||
['已关任务',...this.xmProductStateHiss.map(i=>i.taskCloseCnt)], |
|||
['未关缺陷',...this.xmProductStateHiss.map(i=>i.bugCnt-i.closedBugs)], |
|||
['已关缺陷',...this.xmProductStateHiss.map(i=>i.closedBugs)] |
|||
] |
|||
}, |
|||
titleCpd(){ |
|||
|
|||
var preName="" |
|||
if(this.filters.testPlan && this.filters.testPlan.id){ |
|||
preName=`测试计划【${this.filters.testPlan.name}】` |
|||
}else if(this.filters.testCasedb && this.filters.testCasedb.id){ |
|||
preName=`测试库【${this.filters.testCasedb.name}】` |
|||
}else if(this.filters.iteration && this.filters.iteration.id){ |
|||
preName=`迭代【${this.filters.iteration.iterationName}】` |
|||
}else if(this.filters.product && this.filters.product.id){ |
|||
if(this.filters.product.productName){ |
|||
preName=`产品【${this.filters.product.productName}】` |
|||
}else{ |
|||
preName=`产品【${this.filters.product.id}】` |
|||
} |
|||
|
|||
}else if(this.filters.project && this.filters.project.id){ |
|||
if(this.filters.project.name){ |
|||
preName=`项目【${this.filters.project.name}】` |
|||
}else{ |
|||
preName=`项目【${this.filters.project.id}】` |
|||
} |
|||
} |
|||
return preName+"产品工作项每日分布图" |
|||
}, |
|||
xmProductCpd(){ |
|||
if(this.xmProduct && this.xmProduct.id){ |
|||
return this.xmProduct |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
}, |
|||
watch: { |
|||
dataSetCpd(){ |
|||
this.$nextTick(()=>{ |
|||
this.drawCharts(); |
|||
}) |
|||
|
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
filters:{ |
|||
product:null, |
|||
project:null, |
|||
testPlan:null, |
|||
iteration:null, |
|||
testCasedb:null, |
|||
category:'', |
|||
startBizDate:'', |
|||
endBizDate:'', |
|||
}, |
|||
dicts:{},//下拉选择框的所有静态数据 params=[{categoryId:'0001',itemCode:'sex'}] 返回结果 {'sex':[{optionValue:'1',optionName:'男',seqOrder:'1',fp:'',isDefault:'0'},{optionValue:'2',optionName:'女',seqOrder:'2',fp:'',isDefault:'0'}]} |
|||
load:{ list: false, edit: false, del: false, add: false },//查询中... |
|||
dateRanger:[], |
|||
maxTableHeight:300, |
|||
visible:false, |
|||
xmProductStateHiss:[], |
|||
|
|||
}//end return |
|||
},//end data |
|||
methods: { |
|||
listXmProductStateHis(){ |
|||
if(!this.filters.product){ |
|||
this.$notify({position:'bottom-left',showClose:true,message:'请先选中产品',type:'warning'}) |
|||
return; |
|||
} |
|||
|
|||
var params={productId:this.filters.product.id,orderBy:'biz_date asc'} |
|||
if(this.filters.startBizDate && this.filters.endBizDate){ |
|||
params.startBizDate=this.filters.startBizDate; |
|||
params.endBizDate=this.filters.endBizDate; |
|||
} |
|||
listXmProductStateHis(params).then(res=>{ |
|||
this.xmProductStateHiss=res.data.tips.isOk?res.data.data:this.xmProductStateHiss; |
|||
}) |
|||
}, |
|||
open(){ |
|||
this.visible=true; |
|||
this.filters.testPlan=this.xmTestPlan |
|||
this.filters.product=this.xmProduct |
|||
this.filters.project=this.xmProject |
|||
this.filters.iteration=this.xmIteration |
|||
this.filters.testCasedb=this.xmTestCasedb |
|||
this.xmProductStateHiss=[] |
|||
if(this.$refs['xmProductSelect'])this.$refs['xmProductSelect'].clearSelect(); |
|||
this.$nextTick(()=>{ |
|||
this.listXmProductStateHis(); |
|||
}) |
|||
|
|||
}, |
|||
drawCharts() { |
|||
this.myChart = this.$echarts.init(document.getElementById("productWorkItemDayList")); |
|||
var that=this; |
|||
this.myChart.on('updateAxisPointer', function (event) { |
|||
const xAxisInfo = event.axesInfo[0]; |
|||
if (xAxisInfo) { |
|||
const dimension = xAxisInfo.value + 1; |
|||
that.myChart.setOption({ |
|||
series: { |
|||
id: 'pie', |
|||
label: { |
|||
formatter: '{b}: {@[' + dimension + ']} ({d}%)' |
|||
}, |
|||
encode: { |
|||
value: dimension, |
|||
tooltip: dimension |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
}); |
|||
this.myChart.setOption({ |
|||
|
|||
title: { |
|||
text: this.titleCpd, |
|||
left: 'center' |
|||
}, |
|||
trigger: 'axis', |
|||
tooltip: { |
|||
trigger: 'axis', |
|||
}, |
|||
barMaxWidth: 100, |
|||
toolbox: { |
|||
show: true, |
|||
top:"5%", |
|||
right:"10px", |
|||
feature: { |
|||
dataView: { show: true, readOnly: false }, |
|||
magicType: { show: true, type: ['line', 'bar'] }, |
|||
|
|||
saveAsImage: { show: true } |
|||
} |
|||
}, |
|||
|
|||
calculable: true, |
|||
legend: { |
|||
bottom: 'bottom', |
|||
}, |
|||
|
|||
dataset: { |
|||
source: this.dataSetCpd |
|||
}, |
|||
xAxis: { |
|||
type: 'category', |
|||
}, |
|||
yAxis: { gridIndex: 0 }, |
|||
grid: { top: '55%' }, |
|||
series: [ |
|||
{ name:'未关故事', |
|||
type: 'line', |
|||
seriesLayoutBy: 'row', |
|||
smooth:true, |
|||
emphasis: { focus: 'series' }, |
|||
}, |
|||
{ name:'已关故事', |
|||
type: 'line', |
|||
seriesLayoutBy: 'row', |
|||
smooth:true, |
|||
emphasis: { focus: 'series' }, |
|||
}, |
|||
{ |
|||
name:'未关任务', |
|||
type: 'line', |
|||
seriesLayoutBy: 'row', |
|||
smooth:true, |
|||
emphasis: { focus: 'series' }, |
|||
}, |
|||
{ |
|||
name:'已关任务', |
|||
type: 'line', |
|||
seriesLayoutBy: 'row', |
|||
smooth:true, |
|||
emphasis: { focus: 'series' }, |
|||
}, |
|||
{ name:'未关缺陷', |
|||
type: 'line', |
|||
seriesLayoutBy: 'row', |
|||
smooth:true, |
|||
emphasis: { focus: 'series' }, |
|||
}, |
|||
{ name:'已关缺陷', |
|||
type: 'line', |
|||
seriesLayoutBy: 'row', |
|||
smooth:true, |
|||
emphasis: { focus: 'series' }, |
|||
}, |
|||
{ |
|||
type: 'pie', |
|||
id: 'pie', |
|||
radius: '30%', |
|||
center: ['50%', '30%'], |
|||
emphasis: { |
|||
focus: 'self' |
|||
}, |
|||
label: { |
|||
formatter: '{b}: {@日期} ({d}%)' |
|||
}, |
|||
encode: { |
|||
itemName: '日期', |
|||
value:this.dataSetCpd[0][this.dataSetCpd[0].length-1], |
|||
tooltip: '日期' |
|||
} |
|||
} |
|||
] |
|||
}); |
|||
}, |
|||
|
|||
onProductSelected(product){ |
|||
this.filters.product=product |
|||
this.xmProductStateHiss=[]; |
|||
}, |
|||
|
|||
onProductClear(){ |
|||
this.filters.product=null |
|||
|
|||
this.xmProductStateHiss=[]; |
|||
|
|||
}, |
|||
},//end method |
|||
mounted() { |
|||
/** |
|||
initSimpleDicts('all',['demandSource','demandLvl','demandType','priority','menuStatus'] ).then(res=>{ |
|||
this.dicts=res.data.data; |
|||
}) |
|||
*/ |
|||
this.maxTableHeight = util.calcTableMaxHeight(this.$refs.filtersRef.$el) |
|||
//this.charts(); |
|||
this.open(); |
|||
|
|||
}//end mounted |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style scoped> |
|||
.image { |
|||
width: 100%; |
|||
display: block; |
|||
} |
|||
</style> |
|||
@ -1,334 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row class="padding"> |
|||
<el-popover trigger="manual" v-model="conditionBtnVisible" style="float:right;" width="300"> |
|||
<el-button slot="reference" icon="el-icon-more" @click="conditionBtnVisible=!conditionBtnVisible"></el-button> |
|||
<el-row> |
|||
<el-button type="danger" icon="el-icon-delete" @click="doDelete">删除</el-button> |
|||
<el-button style="float:right;" type="text" icon="el-icon-close" @click="conditionBtnVisible=false">关闭</el-button> |
|||
</el-row> |
|||
<el-form :model="filters"> |
|||
<el-form-item label="分组属性"> |
|||
<el-select v-model="filters.groupBy" @change="onXmQuestionSomeFieldsChange('groupBy',$event)" clearable> |
|||
<el-option v-for="i in this.groupBys" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="缺陷状态" prop="bugStatus"> |
|||
<el-select v-model="filters.bugStatus" @change="onXmQuestionSomeFieldsChange('bugStatus',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugStatus" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="缺陷类型" prop="bugType" > |
|||
<el-select v-model="filters.bugType" @change="onXmQuestionSomeFieldsChange('bugType',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugType" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="缺陷原因" prop="bugReason"> |
|||
<el-select v-model="filters.bugReason" @change="onXmQuestionSomeFieldsChange('bugReason',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugReason" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="严重程度" prop="bugSeverity" > |
|||
<el-select v-model="filters.bugSeverity" @change="onXmQuestionSomeFieldsChange('bugSeverity',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugSeverity" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="优先级" prop="priority" > |
|||
<el-select v-model="filters.priority" @change="onXmQuestionSomeFieldsChange('priority',$event)" clearable> |
|||
<el-option v-for="i in dicts.priority" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="解决方案" prop="solution" > |
|||
<el-select v-model="filters.solution" @change="onXmQuestionSomeFieldsChange('solution',$event)" clearable> |
|||
<el-option v-for="i in dicts.bugSolution" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="重现频率" prop="repRate" > |
|||
<el-select v-model="filters.repRate" @change="onXmQuestionSomeFieldsChange('repRate',$event)" clearable> |
|||
<el-option v-for="i in dicts.bugRepRate" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
|
|||
<el-form-item> |
|||
<el-button type="primary" icon="el-icon-search" @click="searchXmQuestionAttDist">查询</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-popover> |
|||
</el-row> |
|||
<el-row> |
|||
<div> |
|||
<div class="main" :id="id" |
|||
style="width:100%;height:600px;margin:0 auto;"></div> |
|||
<div class="progress"></div> |
|||
</div> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '@/common/js/util';//全局公共库 |
|||
import { initSimpleDicts } from '@/api/mdp/meta/item';//下拉框数据查询 |
|||
import { mapGetters } from 'vuex' |
|||
|
|||
import { getXmQuestionAttDist } from '@/api/xm/core/xmQuestion'; |
|||
|
|||
import XmIterationSelect from '@/views/xm/core/components/XmIterationSelect.vue';//修改界面 |
|||
import XmProductSelect from '@/views/xm/core/components/XmProductSelect';//新增界面 |
|||
|
|||
export default { |
|||
|
|||
components: { |
|||
XmIterationSelect,XmProductSelect, |
|||
}, |
|||
props:['xmTestPlan','xmRptConfig','compCfg','groupBy'], |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo','roles' |
|||
]), |
|||
xmQuestionAttDistsCpd(){ |
|||
if(this.xmQuestionAttDists.length==0){ |
|||
return [] |
|||
}else{ |
|||
var itemId=""; |
|||
if(this.filters.groupBy=='bug_status'){ |
|||
itemId="bugStatus" |
|||
}else if(this.filters.groupBy=='bug_type'){ |
|||
itemId="bugType" |
|||
}else if(this.filters.groupBy=='bug_reason'){ |
|||
itemId="bugReason" |
|||
}else if(this.filters.groupBy=='bug_severity'){ |
|||
itemId="bugSeverity" |
|||
}else if(this.filters.groupBy=='priority'){ |
|||
itemId="priority" |
|||
} else if(this.filters.groupBy=='bug_solution'){ |
|||
itemId="bugSolution" |
|||
} else if(this.filters.groupBy=='rep_rate'){ |
|||
itemId="bugRepRate" |
|||
} |
|||
return this.xmQuestionAttDists.map(i=>{ |
|||
var data={...i} |
|||
data.name=this.formatDict(itemId,data.name) |
|||
return data; |
|||
}) |
|||
} |
|||
}, |
|||
title(){ |
|||
return this.groupBys.find(i=>i.id==this.filters.groupBy).name+'数量分布' |
|||
}, |
|||
legendCpd(){ |
|||
var itemId=""; |
|||
if(this.filters.groupBy=='bug_status'){ |
|||
itemId="bugStatus" |
|||
}else if(this.filters.groupBy=='bug_type'){ |
|||
itemId="bugType" |
|||
}else if(this.filters.groupBy=='bug_reason'){ |
|||
itemId="bugReason" |
|||
}else if(this.filters.groupBy=='bug_severity'){ |
|||
itemId="bugSeverity" |
|||
}else if(this.filters.groupBy=='priority'){ |
|||
itemId="priority" |
|||
} else if(this.filters.groupBy=='bug_solution'){ |
|||
itemId="bugSolution" |
|||
} else if(this.filters.groupBy=='rep_rate'){ |
|||
itemId="bugRepRate" |
|||
} |
|||
|
|||
return this.dicts[itemId].map(i=>i.name) |
|||
}, |
|||
id(){ |
|||
return this.compCfg.id |
|||
}, |
|||
|
|||
}, |
|||
watch: { |
|||
xmQuestionAttDistsCpd(){ |
|||
this.drawCharts(); |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
filters:{ |
|||
groupBy:'bug_status', |
|||
planId:'', |
|||
productId:'', |
|||
projectId:'', |
|||
bugStatus:'', |
|||
bugType:'', |
|||
bugReason:'', |
|||
bugSeverity:'', |
|||
priority:'', |
|||
solution:'', |
|||
repRate:'', |
|||
}, |
|||
groupBys:[ |
|||
{id:'bug_status', name:'缺陷状态'}, |
|||
{id:'bug_type', name:'缺陷类型'}, |
|||
{id:'bug_reason', name:'缺陷原因'}, |
|||
{id:'bug_severity', name:'紧急程度'}, |
|||
{id:'priority', name:'优先级'}, |
|||
{id:'bug_solution', name:'解决方案'}, |
|||
{id:'rep_rate', name:'复现频率'}, |
|||
|
|||
], |
|||
dicts:{},//下拉选择框的所有静态数据 params=[{categoryId:'0001',itemCode:'sex'}] 返回结果 {'sex':[{optionValue:'1',optionName:'男',seqOrder:'1',fp:'',isDefault:'0'},{optionValue:'2',optionName:'女',seqOrder:'2',fp:'',isDefault:'0'}]} |
|||
load:{ list: false, edit: false, del: false, add: false },//查询中... |
|||
dateRanger:[], |
|||
maxTableHeight:300, |
|||
visible:false, |
|||
xmQuestionAttDists:[], |
|||
conditionBtnVisible:false, |
|||
|
|||
}//end return |
|||
},//end data |
|||
methods: { |
|||
formatDict(itemId,val){ |
|||
var dict=this.dicts[itemId] |
|||
if(dict){ |
|||
var item=dict.find(i=>i.id==val) |
|||
if(item){ |
|||
return item.name |
|||
} |
|||
} |
|||
return val; |
|||
}, |
|||
findMax( list ) { |
|||
var i, max = list[0]; |
|||
|
|||
if(list.length < 2) return max; |
|||
|
|||
for (i = 0; i < list.length; i++) { |
|||
if (list[i].distBudgetWorkload > max.distBudgetWorkload) { |
|||
max = list[i]; |
|||
} |
|||
} |
|||
return max; |
|||
}, |
|||
open(params){ |
|||
this.visible=true; |
|||
this.filters.product=params.xmProduct |
|||
this.filters.project=params.xmProject |
|||
this.filters.Product=params.xmProduct |
|||
|
|||
}, |
|||
drawCharts() { |
|||
this.myChart = this.$echarts.init(document.getElementById(this.id)); |
|||
this.myChart.setOption( |
|||
{ |
|||
title: { |
|||
text: this.title, |
|||
left: 'center' |
|||
}, |
|||
tooltip: { |
|||
trigger: 'item', |
|||
|
|||
}, |
|||
|
|||
toolbox: { |
|||
show: true, |
|||
right:"20px", |
|||
feature: { |
|||
dataView: { show: true, readOnly: false }, |
|||
saveAsImage: { show: true }, |
|||
} |
|||
}, |
|||
calculable: true, |
|||
|
|||
legend: { |
|||
top:'5%', |
|||
left: 'center', |
|||
data:this.legendCpd, |
|||
}, |
|||
series: [ |
|||
{ |
|||
type: 'pie', |
|||
radius: '50%', |
|||
data: this.xmQuestionAttDistsCpd, |
|||
emphasis: { |
|||
itemStyle: { |
|||
shadowBlur: 10, |
|||
shadowOffsetX: 0, |
|||
shadowColor: 'rgba(0, 0, 0, 0.5)' |
|||
} |
|||
}, |
|||
|
|||
label: { |
|||
show: true, |
|||
formatter:'{b}: {c} ({d}%)' |
|||
}, |
|||
} |
|||
] |
|||
} |
|||
) |
|||
}, |
|||
onXmQuestionSomeFieldsChange(fieldName,$event){ |
|||
this.xmQuestionAttDists=[] |
|||
}, |
|||
searchXmQuestionAttDist(){ |
|||
if(!this.filters.groupBy){ |
|||
this.$notify({position:'bottom-left',showClose:true,message:'请选中分组属性',type:'warning'}) |
|||
return |
|||
} |
|||
var params={...this.filters} |
|||
|
|||
getXmQuestionAttDist(params).then(res=>{ |
|||
this.xmQuestionAttDists=res.data.data |
|||
}) |
|||
|
|||
}, |
|||
onProductSelected(product){ |
|||
this.filters.product=product |
|||
}, |
|||
|
|||
onProductClear(){ |
|||
this.filters.product=null |
|||
|
|||
}, |
|||
|
|||
onIterationSelected(iteration){ |
|||
this.filters.iteration=iteration |
|||
}, |
|||
|
|||
onIterationClear(){ |
|||
this.filters.iteration=null |
|||
}, |
|||
initData(){ |
|||
if(this.xmTestPlan){ |
|||
this.filters.productId=this.xmTestPlan.productId |
|||
this.filters.projectId=this.xmTestPlan.projectId |
|||
this.filters.planId=this.xmTestPlan.id |
|||
} |
|||
if(this.groupBy){ |
|||
this.filters.groupBy=this.groupBy |
|||
} |
|||
if(this.compCfg && this.compCfg.params){ |
|||
Object.assign(this.filters,this.compCfg.params) |
|||
} |
|||
}, |
|||
doDelete(){ |
|||
this.$emit("delete",this.compCfg) |
|||
}, |
|||
sizeAutoChange(){ |
|||
this.myChart.resize(); |
|||
} |
|||
},//end method |
|||
mounted() { |
|||
initSimpleDicts('all',['bugSeverity','bugSolution','bugStatus','bugType','priority','bugRepRate','bugReason'] ).then(res=>{ |
|||
this.dicts=res.data.data; |
|||
}) |
|||
this.initData(); |
|||
this.searchXmQuestionAttDist(); |
|||
//this.charts(); |
|||
//this.drawCharts(); |
|||
|
|||
}//end mounted |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style scoped> |
|||
.image { |
|||
width: 100%; |
|||
display: block; |
|||
} |
|||
</style> |
|||
@ -1,259 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row class="padding"> |
|||
<el-popover trigger="manual" v-model="conditionBtnVisible" style="float:right;" width="300"> |
|||
|
|||
<el-button slot="reference" icon="el-icon-more" @click="conditionBtnVisible=!conditionBtnVisible"></el-button> |
|||
<el-row> |
|||
<el-button type="danger" icon="el-icon-delete" @click="doDelete">删除</el-button> |
|||
<el-button style="float:right;" type="text" icon="el-icon-close" @click="conditionBtnVisible=false">关闭</el-button> |
|||
</el-row> |
|||
<el-form :model="filters"> |
|||
|
|||
<el-form-item label="缺陷状态" prop="bugStatus"> |
|||
<el-select v-model="filters.bugStatus" @change="onXmQuestionSomeFieldsChange('bugStatus',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugStatus" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="缺陷类型" prop="bugType" > |
|||
<el-select v-model="filters.bugType" @change="onXmQuestionSomeFieldsChange('bugType',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugType" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="缺陷原因" prop="bugReason"> |
|||
<el-select v-model="filters.bugReason" @change="onXmQuestionSomeFieldsChange('bugReason',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugReason" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="严重程度" prop="bugSeverity" > |
|||
<el-select v-model="filters.bugSeverity" @change="onXmQuestionSomeFieldsChange('bugSeverity',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugSeverity" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="优先级" prop="priority" > |
|||
<el-select v-model="filters.priority" @change="onXmQuestionSomeFieldsChange('priority',$event)" clearable> |
|||
<el-option v-for="i in dicts.priority" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="解决方案" prop="solution" > |
|||
<el-select v-model="filters.solution" @change="onXmQuestionSomeFieldsChange('solution',$event)" clearable> |
|||
<el-option v-for="i in dicts.bugSolution" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="重现频率" prop="repRate" > |
|||
<el-select v-model="filters.repRate" @change="onXmQuestionSomeFieldsChange('repRate',$event)" clearable> |
|||
<el-option v-for="i in dicts.bugRepRate" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
|
|||
<el-form-item> |
|||
<el-button type="primary" icon="el-icon-search" @click="searchXmQuestionAgeDist">查询</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-popover> |
|||
</el-row> |
|||
<el-row> |
|||
<div> |
|||
<div class="main" :id="id" |
|||
style="width:100%;height:600px;margin:0 auto;"></div> |
|||
<div class="progress"></div> |
|||
</div> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '@/common/js/util';//全局公共库 |
|||
import { initSimpleDicts } from '@/api/mdp/meta/item';//下拉框数据查询 |
|||
import { mapGetters } from 'vuex' |
|||
|
|||
import { getXmQuestionAgeDist } from '@/api/xm/core/xmQuestion'; |
|||
|
|||
import XmIterationSelect from '@/views/xm/core/components/XmIterationSelect.vue';//修改界面 |
|||
import XmProductSelect from '@/views/xm/core/components/XmProductSelect';//新增界面 |
|||
|
|||
export default { |
|||
|
|||
components: { |
|||
XmIterationSelect,XmProductSelect, |
|||
}, |
|||
props:['xmTestPlan','xmRptConfig','compCfg'], |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo','roles' |
|||
]), |
|||
xmQuestionAgeDistsCpd(){ |
|||
if(this.xmQuestionAgeDists.length==0){ |
|||
return [] |
|||
}else{ |
|||
var datas=[] |
|||
this.xmQuestionAgeDists.forEach(i=>{ |
|||
var data={...i} |
|||
data.name=this.legendCpd[i.name] |
|||
datas.push(data) |
|||
}) |
|||
return datas; |
|||
} |
|||
}, |
|||
title(){ |
|||
return '缺陷年龄数量分布' |
|||
}, |
|||
legendCpd(){ |
|||
return ['0-2天','3-5天','6-7天','8-15天','16-30天','30天以上'] |
|||
}, |
|||
id(){ |
|||
return this.compCfg.id |
|||
} |
|||
|
|||
}, |
|||
watch: { |
|||
xmQuestionAgeDistsCpd(){ |
|||
this.drawCharts(); |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
filters:{ |
|||
planId:'', |
|||
productId:'', |
|||
projectId:'', |
|||
bugStatus:'', |
|||
bugType:'', |
|||
bugReason:'', |
|||
bugSeverity:'', |
|||
priority:'', |
|||
solution:'', |
|||
repRate:'', |
|||
|
|||
|
|||
}, |
|||
dicts:{},//下拉选择框的所有静态数据 params=[{categoryId:'0001',itemCode:'sex'}] 返回结果 {'sex':[{optionValue:'1',optionName:'男',seqOrder:'1',fp:'',isDefault:'0'},{optionValue:'2',optionName:'女',seqOrder:'2',fp:'',isDefault:'0'}]} |
|||
load:{ list: false, edit: false, del: false, add: false },//查询中... |
|||
dateRanger:[], |
|||
maxTableHeight:300, |
|||
visible:false, |
|||
xmQuestionAgeDists:[], |
|||
conditionBtnVisible:false, |
|||
|
|||
}//end return |
|||
},//end data |
|||
methods: { |
|||
drawCharts() { |
|||
this.myChart = this.$echarts.init(document.getElementById(this.id)); |
|||
this.myChart.setOption( |
|||
{ |
|||
title: { |
|||
text: this.title, |
|||
left: 'center' |
|||
}, |
|||
tooltip: { |
|||
trigger: 'item', |
|||
|
|||
}, |
|||
|
|||
toolbox: { |
|||
show: true, |
|||
right:"20px", |
|||
feature: { |
|||
dataView: { show: true, readOnly: false }, |
|||
saveAsImage: { show: true }, |
|||
} |
|||
}, |
|||
calculable: true, |
|||
|
|||
legend: { |
|||
top:'5%', |
|||
left: 'center', |
|||
data:this.legendCpd, |
|||
}, |
|||
series: [ |
|||
{ |
|||
type: 'pie', |
|||
radius: '50%', |
|||
data: this.xmQuestionAgeDistsCpd, |
|||
emphasis: { |
|||
itemStyle: { |
|||
shadowBlur: 10, |
|||
shadowOffsetX: 0, |
|||
shadowColor: 'rgba(0, 0, 0, 0.5)' |
|||
} |
|||
}, |
|||
|
|||
label: { |
|||
show: true, |
|||
formatter:'{b}: {c} ({d}%)' |
|||
}, |
|||
} |
|||
] |
|||
} |
|||
) |
|||
}, |
|||
onXmQuestionSomeFieldsChange(fieldName,$event){ |
|||
this.xmQuestionAgeDists=[] |
|||
}, |
|||
searchXmQuestionAgeDist(){ |
|||
var params={...this.filters} |
|||
if(this.xmTestPlan && this.xmTestPlan.id){ |
|||
params.planId=this.xmTestPlan.id |
|||
} |
|||
|
|||
getXmQuestionAgeDist(params).then(res=>{ |
|||
this.xmQuestionAgeDists=res.data.data |
|||
}) |
|||
|
|||
}, |
|||
onProductSelected(product){ |
|||
this.filters.product=product |
|||
}, |
|||
|
|||
onProductClear(){ |
|||
this.filters.product=null |
|||
|
|||
}, |
|||
|
|||
onIterationSelected(iteration){ |
|||
this.filters.iteration=iteration |
|||
}, |
|||
doDelete(){ |
|||
this.$emit("delete",this.compCfg) |
|||
}, |
|||
|
|||
onIterationClear(){ |
|||
this.filters.iteration=null |
|||
}, |
|||
initData(){ |
|||
|
|||
if(this.xmTestPlan){ |
|||
this.filters.productId=this.xmTestPlan.productId |
|||
this.filters.projectId=this.xmTestPlan.projectId |
|||
this.filters.planId=this.xmTestPlan.id |
|||
} |
|||
if(this.compCfg && this.compCfg.params){ |
|||
Object.assign(this.filters,this.compCfg.params) |
|||
} |
|||
}, |
|||
sizeAutoChange(){ |
|||
this.myChart.resize(); |
|||
} |
|||
},//end method |
|||
mounted() { |
|||
initSimpleDicts('all',['bugSeverity','bugSolution','bugStatus','bugType','priority','bugRepRate','bugReason'] ).then(res=>{ |
|||
this.dicts=res.data.data; |
|||
}) |
|||
this.initData(); |
|||
this.searchXmQuestionAgeDist(); |
|||
//this.charts(); |
|||
//this.drawCharts(); |
|||
|
|||
}//end mounted |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style scoped> |
|||
.image { |
|||
width: 100%; |
|||
display: block; |
|||
} |
|||
</style> |
|||
@ -1,48 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row> |
|||
<question-sort :ref="compCfg.id" :xm-test-plan="xmTestPlan" :comp-cfg="compCfg" :rpt-config-visible="rptConfigVisible" :group-by="'ask_userid'" @delete="$emit('delete',$event)"/> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import questionSort from './questionSort' |
|||
import { mapGetters } from 'vuex' |
|||
import dayjs from 'dayjs' |
|||
|
|||
export default { |
|||
props:['xmTestPlan','compCfg'], |
|||
components: {questionSort}, |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo' |
|||
]), |
|||
}, |
|||
|
|||
watch: { |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
rptConfigVisible:false, |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
sizeAutoChange(){ |
|||
this.refs[this.compCfg.id].sizeAutoChange() |
|||
} |
|||
}, |
|||
|
|||
|
|||
mounted() { |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
</style> |
|||
@ -1,334 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row class="padding"> |
|||
<el-popover trigger="manual" v-model="conditionBtnVisible" style="float:right;" width="300"> |
|||
<el-button slot="reference" icon="el-icon-more" @click="conditionBtnVisible=!conditionBtnVisible"></el-button> |
|||
<el-row> |
|||
<el-button type="danger" icon="el-icon-delete" @click="doDelete">删除</el-button> |
|||
<el-button style="float:right;" type="text" icon="el-icon-close" @click="conditionBtnVisible=false">关闭</el-button> |
|||
</el-row> |
|||
<el-form :model="filters"> |
|||
<el-form-item label="分组属性"> |
|||
<el-select v-model="filters.groupBy" @change="onXmQuestionSomeFieldsChange('groupBy',$event)" clearable> |
|||
<el-option v-for="i in this.groupBys" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="缺陷状态" prop="bugStatus"> |
|||
<el-select v-model="filters.bugStatus" @change="onXmQuestionSomeFieldsChange('bugStatus',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugStatus" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="缺陷类型" prop="bugType" > |
|||
<el-select v-model="filters.bugType" @change="onXmQuestionSomeFieldsChange('bugType',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugType" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="缺陷原因" prop="bugReason"> |
|||
<el-select v-model="filters.bugReason" @change="onXmQuestionSomeFieldsChange('bugReason',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugReason" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="严重程度" prop="bugSeverity" > |
|||
<el-select v-model="filters.bugSeverity" @change="onXmQuestionSomeFieldsChange('bugSeverity',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugSeverity" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="优先级" prop="priority" > |
|||
<el-select v-model="filters.priority" @change="onXmQuestionSomeFieldsChange('priority',$event)" clearable> |
|||
<el-option v-for="i in dicts.priority" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="解决方案" prop="solution" > |
|||
<el-select v-model="filters.solution" @change="onXmQuestionSomeFieldsChange('solution',$event)" clearable> |
|||
<el-option v-for="i in dicts.bugSolution" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="重现频率" prop="repRate" > |
|||
<el-select v-model="filters.repRate" @change="onXmQuestionSomeFieldsChange('repRate',$event)" clearable> |
|||
<el-option v-for="i in dicts.bugRepRate" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
|
|||
<el-form-item> |
|||
<el-button type="primary" icon="el-icon-search" @click="searchXmQuestionAttDist">查询</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-popover> |
|||
</el-row> |
|||
<el-row> |
|||
<div> |
|||
<div class="main" :id="id" |
|||
style="width:100%;height:600px;margin:0 auto;"></div> |
|||
<div class="progress"></div> |
|||
</div> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '@/common/js/util';//全局公共库 |
|||
import { initSimpleDicts } from '@/api/mdp/meta/item';//下拉框数据查询 |
|||
import { mapGetters } from 'vuex' |
|||
|
|||
import { getXmQuestionAttDist } from '@/api/xm/core/xmQuestion'; |
|||
|
|||
import XmIterationSelect from '@/views/xm/core/components/XmIterationSelect.vue';//修改界面 |
|||
import XmProductSelect from '@/views/xm/core/components/XmProductSelect';//新增界面 |
|||
|
|||
export default { |
|||
|
|||
components: { |
|||
XmIterationSelect,XmProductSelect, |
|||
}, |
|||
props:['xmTestPlan','xmRptConfig','compCfg','groupBy'], |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo','roles' |
|||
]), |
|||
xmQuestionAttDistsCpd(){ |
|||
if(this.xmQuestionAttDists.length==0){ |
|||
return [] |
|||
}else{ |
|||
var itemId=""; |
|||
if(this.filters.groupBy=='bug_status'){ |
|||
itemId="bugStatus" |
|||
}else if(this.filters.groupBy=='bug_type'){ |
|||
itemId="bugType" |
|||
}else if(this.filters.groupBy=='bug_reason'){ |
|||
itemId="bugReason" |
|||
}else if(this.filters.groupBy=='bug_severity'){ |
|||
itemId="bugSeverity" |
|||
}else if(this.filters.groupBy=='priority'){ |
|||
itemId="priority" |
|||
} else if(this.filters.groupBy=='solution'){ |
|||
itemId="bugSolution" |
|||
} else if(this.filters.groupBy=='rep_rate'){ |
|||
itemId="bugRepRate" |
|||
} |
|||
return this.xmQuestionAttDists.map(i=>{ |
|||
var data={...i} |
|||
data.name=this.formatDict(itemId,data.name) |
|||
return data; |
|||
}) |
|||
} |
|||
}, |
|||
title(){ |
|||
return this.groupBys.find(i=>i.id==this.filters.groupBy).name+'数量分布' |
|||
}, |
|||
legendCpd(){ |
|||
var itemId=""; |
|||
if(this.filters.groupBy=='bug_status'){ |
|||
itemId="bugStatus" |
|||
}else if(this.filters.groupBy=='bug_type'){ |
|||
itemId="bugType" |
|||
}else if(this.filters.groupBy=='bug_reason'){ |
|||
itemId="bugReason" |
|||
}else if(this.filters.groupBy=='bug_severity'){ |
|||
itemId="bugSeverity" |
|||
}else if(this.filters.groupBy=='priority'){ |
|||
itemId="priority" |
|||
} else if(this.filters.groupBy=='solution'){ |
|||
itemId="bugSolution" |
|||
} else if(this.filters.groupBy=='rep_rate'){ |
|||
itemId="bugRepRate" |
|||
} |
|||
|
|||
return this.dicts[itemId].map(i=>i.name) |
|||
}, |
|||
id(){ |
|||
return this.compCfg.id |
|||
}, |
|||
|
|||
}, |
|||
watch: { |
|||
xmQuestionAttDistsCpd(){ |
|||
this.drawCharts(); |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
filters:{ |
|||
groupBy:'bug_status', |
|||
planId:'', |
|||
productId:'', |
|||
projectId:'', |
|||
bugStatus:'', |
|||
bugType:'', |
|||
bugReason:'', |
|||
bugSeverity:'', |
|||
priority:'', |
|||
solution:'', |
|||
repRate:'', |
|||
}, |
|||
groupBys:[ |
|||
{id:'bug_status', name:'缺陷状态'}, |
|||
{id:'bug_type', name:'缺陷类型'}, |
|||
{id:'bug_reason', name:'缺陷原因'}, |
|||
{id:'bug_severity', name:'紧急程度'}, |
|||
{id:'priority', name:'优先级'}, |
|||
{id:'solution', name:'解决方案'}, |
|||
{id:'rep_rate', name:'复现频率'}, |
|||
|
|||
], |
|||
dicts:{},//下拉选择框的所有静态数据 params=[{categoryId:'0001',itemCode:'sex'}] 返回结果 {'sex':[{optionValue:'1',optionName:'男',seqOrder:'1',fp:'',isDefault:'0'},{optionValue:'2',optionName:'女',seqOrder:'2',fp:'',isDefault:'0'}]} |
|||
load:{ list: false, edit: false, del: false, add: false },//查询中... |
|||
dateRanger:[], |
|||
maxTableHeight:300, |
|||
visible:false, |
|||
xmQuestionAttDists:[], |
|||
conditionBtnVisible:false, |
|||
|
|||
}//end return |
|||
},//end data |
|||
methods: { |
|||
formatDict(itemId,val){ |
|||
var dict=this.dicts[itemId] |
|||
if(dict){ |
|||
var item=dict.find(i=>i.id==val) |
|||
if(item){ |
|||
return item.name |
|||
} |
|||
} |
|||
return val; |
|||
}, |
|||
findMax( list ) { |
|||
var i, max = list[0]; |
|||
|
|||
if(list.length < 2) return max; |
|||
|
|||
for (i = 0; i < list.length; i++) { |
|||
if (list[i].distBudgetWorkload > max.distBudgetWorkload) { |
|||
max = list[i]; |
|||
} |
|||
} |
|||
return max; |
|||
}, |
|||
open(params){ |
|||
this.visible=true; |
|||
this.filters.product=params.xmProduct |
|||
this.filters.project=params.xmProject |
|||
this.filters.Product=params.xmProduct |
|||
|
|||
}, |
|||
drawCharts() { |
|||
this.myChart = this.$echarts.init(document.getElementById(this.id)); |
|||
this.myChart.setOption( |
|||
{ |
|||
title: { |
|||
text: this.title, |
|||
left: 'center' |
|||
}, |
|||
tooltip: { |
|||
trigger: 'item', |
|||
|
|||
}, |
|||
|
|||
toolbox: { |
|||
show: true, |
|||
right:"20px", |
|||
feature: { |
|||
dataView: { show: true, readOnly: false }, |
|||
saveAsImage: { show: true }, |
|||
} |
|||
}, |
|||
calculable: true, |
|||
|
|||
legend: { |
|||
top:'5%', |
|||
left: 'center', |
|||
data:this.legendCpd, |
|||
}, |
|||
series: [ |
|||
{ |
|||
type: 'pie', |
|||
radius: '50%', |
|||
data: this.xmQuestionAttDistsCpd, |
|||
emphasis: { |
|||
itemStyle: { |
|||
shadowBlur: 10, |
|||
shadowOffsetX: 0, |
|||
shadowColor: 'rgba(0, 0, 0, 0.5)' |
|||
} |
|||
}, |
|||
|
|||
label: { |
|||
show: true, |
|||
formatter:'{b}: {c} ({d}%)' |
|||
}, |
|||
} |
|||
] |
|||
} |
|||
) |
|||
}, |
|||
onXmQuestionSomeFieldsChange(fieldName,$event){ |
|||
this.xmQuestionAttDists=[] |
|||
}, |
|||
searchXmQuestionAttDist(){ |
|||
if(!this.filters.groupBy){ |
|||
this.$notify({position:'bottom-left',showClose:true,message:'请选中分组属性',type:'warning'}) |
|||
return |
|||
} |
|||
var params={...this.filters} |
|||
|
|||
getXmQuestionAttDist(params).then(res=>{ |
|||
this.xmQuestionAttDists=res.data.data |
|||
}) |
|||
|
|||
}, |
|||
onProductSelected(product){ |
|||
this.filters.product=product |
|||
}, |
|||
|
|||
onProductClear(){ |
|||
this.filters.product=null |
|||
|
|||
}, |
|||
|
|||
onIterationSelected(iteration){ |
|||
this.filters.iteration=iteration |
|||
}, |
|||
|
|||
onIterationClear(){ |
|||
this.filters.iteration=null |
|||
}, |
|||
initData(){ |
|||
if(this.xmTestPlan){ |
|||
this.filters.productId=this.xmTestPlan.productId |
|||
this.filters.projectId=this.xmTestPlan.projectId |
|||
this.filters.planId=this.xmTestPlan.id |
|||
} |
|||
if(this.groupBy){ |
|||
this.filters.groupBy=this.groupBy |
|||
} |
|||
if(this.compCfg && this.compCfg.params){ |
|||
Object.assign(this.filters,this.compCfg.params) |
|||
} |
|||
}, |
|||
doDelete(){ |
|||
this.$emit("delete",this.compCfg) |
|||
}, |
|||
sizeAutoChange(){ |
|||
this.myChart.resize(); |
|||
} |
|||
},//end method |
|||
mounted() { |
|||
initSimpleDicts('all',['bugSeverity','bugSolution','bugStatus','bugType','priority','bugRepRate','bugReason'] ).then(res=>{ |
|||
this.dicts=res.data.data; |
|||
}) |
|||
this.initData(); |
|||
this.searchXmQuestionAttDist(); |
|||
//this.charts(); |
|||
//this.drawCharts(); |
|||
|
|||
}//end mounted |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style scoped> |
|||
.image { |
|||
width: 100%; |
|||
display: block; |
|||
} |
|||
</style> |
|||
@ -1,47 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row> |
|||
<question-att-dist :ref="compCfg.id" :xm-test-plan="xmTestPlan" :comp-cfg="compCfg" :rpt-config-visible="rptConfigVisible" :group-by="'bug_reason'" @delete="$emit('delete',$event)"/> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import questionAttDist from './questionAttDist' |
|||
import { mapGetters } from 'vuex' |
|||
import dayjs from 'dayjs' |
|||
|
|||
export default { |
|||
props:['xmTestPlan','compCfg'], |
|||
components: {questionAttDist}, |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo' |
|||
]), |
|||
}, |
|||
|
|||
watch: { |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
rptConfigVisible:false, |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
sizeAutoChange(){ |
|||
this.refs[this.compCfg.id].sizeAutoChange() |
|||
} |
|||
}, |
|||
|
|||
|
|||
mounted() { |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
</style> |
|||
@ -1,48 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row> |
|||
<question-att-dist :ref="compCfg.id" :xm-test-plan="xmTestPlan" :comp-cfg="compCfg" :rpt-config-visible="rptConfigVisible" :group-by="'bug_severity'" @delete="$emit('delete',$event)"/> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import questionAttDist from './questionAttDist' |
|||
import { mapGetters } from 'vuex' |
|||
import dayjs from 'dayjs' |
|||
|
|||
export default { |
|||
props:['xmTestPlan','compCfg'], |
|||
components: {questionAttDist}, |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo' |
|||
]), |
|||
}, |
|||
|
|||
watch: { |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
rptConfigVisible:false, |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
sizeAutoChange(){ |
|||
this.refs[this.compCfg.id].sizeAutoChange() |
|||
} |
|||
}, |
|||
|
|||
|
|||
mounted() { |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
</style> |
|||
@ -1,48 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row> |
|||
<question-att-dist :ref="compCfg.id" :xm-test-plan="xmTestPlan" :comp-cfg="compCfg" :rpt-config-visible="rptConfigVisible" :group-by="'bug_status'" @delete="$emit('delete',$event)"/> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import questionAttDist from './questionAttDist' |
|||
import { mapGetters } from 'vuex' |
|||
import dayjs from 'dayjs' |
|||
|
|||
export default { |
|||
props:['xmTestPlan','compCfg'], |
|||
components: {questionAttDist}, |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo' |
|||
]), |
|||
}, |
|||
|
|||
watch: { |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
rptConfigVisible:false, |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
sizeAutoChange(){ |
|||
this.refs[this.compCfg.id].sizeAutoChange() |
|||
} |
|||
}, |
|||
|
|||
|
|||
mounted() { |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
</style> |
|||
@ -1,48 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row> |
|||
<question-att-dist :ref="compCfg.id" :xm-test-plan="xmTestPlan" :comp-cfg="compCfg" :rpt-config-visible="rptConfigVisible" :group-by="'bug_type'" @delete="$emit('delete',$event)"/> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import questionAttDist from './questionAttDist' |
|||
import { mapGetters } from 'vuex' |
|||
import dayjs from 'dayjs' |
|||
|
|||
export default { |
|||
props:['xmTestPlan','compCfg'], |
|||
components: {questionAttDist}, |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo' |
|||
]), |
|||
}, |
|||
|
|||
watch: { |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
rptConfigVisible:false, |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
sizeAutoChange(){ |
|||
this.refs[this.compCfg.id].sizeAutoChange() |
|||
} |
|||
}, |
|||
|
|||
|
|||
mounted() { |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
</style> |
|||
@ -1,48 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row> |
|||
<question-sort :ref="compCfg.id" :xm-test-plan="xmTestPlan" :comp-cfg="compCfg" :rpt-config-visible="rptConfigVisible" :group-by="'func_id'" @delete="$emit('delete',$event)"/> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import questionSort from './questionSort' |
|||
import { mapGetters } from 'vuex' |
|||
import dayjs from 'dayjs' |
|||
|
|||
export default { |
|||
props:['xmTestPlan','compCfg'], |
|||
components: {questionSort}, |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo' |
|||
]), |
|||
}, |
|||
|
|||
watch: { |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
rptConfigVisible:false, |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
sizeAutoChange(){ |
|||
this.refs[this.compCfg.id].sizeAutoChange() |
|||
} |
|||
}, |
|||
|
|||
|
|||
mounted() { |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
</style> |
|||
@ -1,48 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row> |
|||
<question-sort :ref="compCfg.id" :xm-test-plan="xmTestPlan" :comp-cfg="compCfg" :rpt-config-visible="rptConfigVisible" :group-by="'handler_userid'" @delete="$emit('delete',$event)"/> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import questionSort from './questionSort' |
|||
import { mapGetters } from 'vuex' |
|||
import dayjs from 'dayjs' |
|||
|
|||
export default { |
|||
props:['xmTestPlan','compCfg'], |
|||
components: {questionSort}, |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo' |
|||
]), |
|||
}, |
|||
|
|||
watch: { |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
rptConfigVisible:false, |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
sizeAutoChange(){ |
|||
this.refs[this.compCfg.id].sizeAutoChange() |
|||
} |
|||
}, |
|||
|
|||
|
|||
mounted() { |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
</style> |
|||
@ -1,48 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row> |
|||
<question-sort :ref="compCfg.id" :xm-test-plan="xmTestPlan" :comp-cfg="compCfg" :rpt-config-visible="rptConfigVisible" :group-by="'menu_id'" @delete="$emit('delete',$event)" /> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import questionSort from './questionSort' |
|||
import { mapGetters } from 'vuex' |
|||
import dayjs from 'dayjs' |
|||
|
|||
export default { |
|||
props:['xmTestPlan','compCfg'], |
|||
components: {questionSort}, |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo' |
|||
]), |
|||
}, |
|||
|
|||
watch: { |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
rptConfigVisible:false, |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
sizeAutoChange(){ |
|||
this.refs[this.compCfg.id].sizeAutoChange() |
|||
} |
|||
}, |
|||
|
|||
|
|||
mounted() { |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
</style> |
|||
@ -1,48 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row> |
|||
<question-att-dist :ref="compCfg.id" :xm-test-plan="xmTestPlan" :comp-cfg="compCfg" :rpt-config-visible="rptConfigVisible" :group-by="'bug_type'" @delete="$emit('delete',$event)"/> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import questionAttDist from './questionAttDist' |
|||
import { mapGetters } from 'vuex' |
|||
import dayjs from 'dayjs' |
|||
|
|||
export default { |
|||
props:['xmTestPlan','compCfg'], |
|||
components: {questionAttDist}, |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo' |
|||
]), |
|||
}, |
|||
|
|||
watch: { |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
rptConfigVisible:false, |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
sizeAutoChange(){ |
|||
this.refs[this.compCfg.id].sizeAutoChange() |
|||
} |
|||
}, |
|||
|
|||
|
|||
mounted() { |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
</style> |
|||
@ -1,48 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row> |
|||
<question-att-dist :ref="compCfg.id" :xm-test-plan="xmTestPlan" :comp-cfg="compCfg" :rpt-config-visible="rptConfigVisible" :group-by="'rep_rate'" @delete="$emit('delete',$event)"/> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import questionAttDist from './questionAttDist' |
|||
import { mapGetters } from 'vuex' |
|||
import dayjs from 'dayjs' |
|||
|
|||
export default { |
|||
props:['xmTestPlan','compCfg'], |
|||
components: {questionAttDist}, |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo' |
|||
]), |
|||
}, |
|||
|
|||
watch: { |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
rptConfigVisible:false, |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
sizeAutoChange(){ |
|||
this.refs[this.compCfg.id].sizeAutoChange() |
|||
} |
|||
}, |
|||
|
|||
|
|||
mounted() { |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
</style> |
|||
@ -1,275 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row class="padding"> |
|||
<el-popover trigger="manual" v-model="conditionBtnVisible" style="float:right;" width="300"> |
|||
|
|||
<el-button slot="reference" icon="el-icon-more" @click="conditionBtnVisible=!conditionBtnVisible"></el-button> |
|||
<el-row> |
|||
<el-button type="danger" icon="el-icon-delete" @click="doDelete">删除</el-button> |
|||
<el-button style="float:right;" type="text" icon="el-icon-close" @click="conditionBtnVisible=false">关闭</el-button> |
|||
</el-row> |
|||
<el-form :model="filters"> |
|||
|
|||
<el-form-item label="缺陷状态" prop="bugStatus"> |
|||
<el-select v-model="filters.bugStatus" @change="onXmQuestionSomeFieldsChange('bugStatus',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugStatus" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="缺陷类型" prop="bugType" > |
|||
<el-select v-model="filters.bugType" @change="onXmQuestionSomeFieldsChange('bugType',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugType" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="缺陷原因" prop="bugReason"> |
|||
<el-select v-model="filters.bugReason" @change="onXmQuestionSomeFieldsChange('bugReason',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugReason" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="严重程度" prop="bugSeverity" > |
|||
<el-select v-model="filters.bugSeverity" @change="onXmQuestionSomeFieldsChange('bugSeverity',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugSeverity" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="优先级" prop="priority" > |
|||
<el-select v-model="filters.priority" @change="onXmQuestionSomeFieldsChange('priority',$event)" clearable> |
|||
<el-option v-for="i in dicts.priority" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="解决方案" prop="solution" > |
|||
<el-select v-model="filters.solution" @change="onXmQuestionSomeFieldsChange('solution',$event)" clearable> |
|||
<el-option v-for="i in dicts.bugSolution" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="重现频率" prop="repRate" > |
|||
<el-select v-model="filters.repRate" @change="onXmQuestionSomeFieldsChange('repRate',$event)" clearable> |
|||
<el-option v-for="i in dicts.bugRepRate" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
|
|||
<el-form-item> |
|||
<el-button type="primary" icon="el-icon-search" @click="searchXmQuestionRetestDist">查询</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-popover> |
|||
</el-row> |
|||
<el-row> |
|||
<div> |
|||
<div class="main" :id="id" |
|||
style="width:100%;height:600px;margin:0 auto;"></div> |
|||
<div class="progress"></div> |
|||
</div> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '@/common/js/util';//全局公共库 |
|||
import { initSimpleDicts } from '@/api/mdp/meta/item';//下拉框数据查询 |
|||
import { mapGetters } from 'vuex' |
|||
|
|||
import { getXmQuestionRetestDist } from '@/api/xm/core/xmQuestion'; |
|||
|
|||
export default { |
|||
|
|||
components: { |
|||
}, |
|||
props:['xmTestPlan','xmRptConfig','compCfg'], |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo','roles' |
|||
]), |
|||
|
|||
xmQuestionRetestDistsCpd(){ |
|||
var def=[ |
|||
{name:"1次",value:0} , |
|||
{name:"2次",value:0} , |
|||
{name:"3次",value:0} , |
|||
{name:"4次",value:0} , |
|||
{name:"5次",value:0} , |
|||
{name:"5次以上",value:0} |
|||
] |
|||
if(this.xmQuestionRetestDists.length==0){ |
|||
return def |
|||
}else{ |
|||
var datas=[] |
|||
this.xmQuestionRetestDists.forEach(i=>{ |
|||
var data={} |
|||
if(i.retimes>5){ |
|||
data.name="5次以上" |
|||
}else{ |
|||
data.name=this.legendCpd[i.retimes] |
|||
} |
|||
data.value=i.bugsNum |
|||
datas.push(data) |
|||
}) |
|||
def.forEach(k=>{ |
|||
if(!datas.some(i=>k.name==i.name)){ |
|||
datas.push(k) |
|||
} |
|||
}) |
|||
return datas; |
|||
} |
|||
}, |
|||
legendCpd(){ |
|||
return ["1次","2次","3次","4次","5次","5次以上"] |
|||
}, |
|||
title(){ |
|||
return '缺陷回归分布' |
|||
}, |
|||
id(){ |
|||
return this.compCfg.id |
|||
} |
|||
|
|||
}, |
|||
watch: { |
|||
xmQuestionRetestDistsCpd(){ |
|||
this.drawCharts(); |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
filters:{ |
|||
planId:'', |
|||
productId:'', |
|||
projectId:'', |
|||
bugStatus:'', |
|||
bugType:'', |
|||
bugReason:'', |
|||
bugSeverity:'', |
|||
priority:'', |
|||
solution:'', |
|||
repRate:'', |
|||
|
|||
|
|||
}, |
|||
dicts:{},//下拉选择框的所有静态数据 params=[{categoryId:'0001',itemCode:'sex'}] 返回结果 {'sex':[{optionValue:'1',optionName:'男',seqOrder:'1',fp:'',isDefault:'0'},{optionValue:'2',optionName:'女',seqOrder:'2',fp:'',isDefault:'0'}]} |
|||
load:{ list: false, edit: false, del: false, add: false },//查询中... |
|||
dateRanger:[], |
|||
maxTableHeight:300, |
|||
visible:false, |
|||
xmQuestionRetestDists:[], |
|||
conditionBtnVisible:false, |
|||
|
|||
}//end return |
|||
},//end data |
|||
methods: { |
|||
drawCharts() { |
|||
this.myChart = this.$echarts.init(document.getElementById(this.id)); |
|||
this.myChart.setOption( |
|||
{ |
|||
title: { |
|||
text: this.title, |
|||
left: 'center' |
|||
}, |
|||
tooltip: { |
|||
trigger: 'item', |
|||
|
|||
}, |
|||
|
|||
toolbox: { |
|||
show: true, |
|||
right:"20px", |
|||
feature: { |
|||
dataView: { show: true, readOnly: false }, |
|||
saveAsImage: { show: true }, |
|||
} |
|||
}, |
|||
calculable: true, |
|||
|
|||
legend: { |
|||
top:'5%', |
|||
left: 'center', |
|||
data:this.legendCpd, |
|||
}, |
|||
series: [ |
|||
{ |
|||
type: 'pie', |
|||
radius: '50%', |
|||
data: this.xmQuestionRetestDistsCpd, |
|||
emphasis: { |
|||
itemStyle: { |
|||
shadowBlur: 10, |
|||
shadowOffsetX: 0, |
|||
shadowColor: 'rgba(0, 0, 0, 0.5)' |
|||
} |
|||
}, |
|||
|
|||
label: { |
|||
show: true, |
|||
formatter:'{b}: {c} ({d}%)' |
|||
}, |
|||
} |
|||
] |
|||
} |
|||
) |
|||
}, |
|||
onXmQuestionSomeFieldsChange(fieldName,$event){ |
|||
this.xmQuestionRetestDists=[] |
|||
}, |
|||
searchXmQuestionRetestDist(){ |
|||
var params={...this.filters} |
|||
if(this.xmTestPlan && this.xmTestPlan.id){ |
|||
params.planId=this.xmTestPlan.id |
|||
} |
|||
|
|||
getXmQuestionRetestDist(params).then(res=>{ |
|||
this.xmQuestionRetestDists=res.data.data |
|||
}) |
|||
|
|||
}, |
|||
onProductSelected(product){ |
|||
this.filters.product=product |
|||
}, |
|||
|
|||
onProductClear(){ |
|||
this.filters.product=null |
|||
|
|||
}, |
|||
|
|||
onIterationSelected(iteration){ |
|||
this.filters.iteration=iteration |
|||
}, |
|||
doDelete(){ |
|||
this.$emit("delete",this.compCfg) |
|||
}, |
|||
|
|||
onIterationClear(){ |
|||
this.filters.iteration=null |
|||
}, |
|||
initData(){ |
|||
|
|||
if(this.xmTestPlan){ |
|||
this.filters.productId=this.xmTestPlan.productId |
|||
this.filters.projectId=this.xmTestPlan.projectId |
|||
this.filters.planId=this.xmTestPlan.id |
|||
} |
|||
if(this.compCfg && this.compCfg.params){ |
|||
Object.assign(this.filters,this.compCfg.params) |
|||
} |
|||
this.drawCharts(); |
|||
}, |
|||
sizeAutoChange(){ |
|||
this.myChart.resize(); |
|||
} |
|||
},//end method |
|||
mounted() { |
|||
initSimpleDicts('all',['bugSeverity','bugSolution','bugStatus','bugType','priority','bugRepRate','bugReason'] ).then(res=>{ |
|||
this.dicts=res.data.data; |
|||
}) |
|||
this.initData(); |
|||
this.searchXmQuestionRetestDist(); |
|||
//this.charts(); |
|||
//this.drawCharts(); |
|||
|
|||
}//end mounted |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style scoped> |
|||
.image { |
|||
width: 100%; |
|||
display: block; |
|||
} |
|||
</style> |
|||
@ -1,48 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row> |
|||
<question-att-dist :ref="compCfg.id" :xm-test-plan="xmTestPlan" :comp-cfg="compCfg" :rpt-config-visible="rptConfigVisible" :group-by="'solution'" @delete="$emit('delete',$event)"/> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import questionAttDist from './questionAttDist' |
|||
import { mapGetters } from 'vuex' |
|||
import dayjs from 'dayjs' |
|||
|
|||
export default { |
|||
props:['xmTestPlan','compCfg'], |
|||
components: {questionAttDist}, |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo' |
|||
]), |
|||
}, |
|||
|
|||
watch: { |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
rptConfigVisible:false, |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
sizeAutoChange(){ |
|||
this.refs[this.compCfg.id].sizeAutoChange() |
|||
} |
|||
}, |
|||
|
|||
|
|||
mounted() { |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
</style> |
|||
@ -1,282 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row class="padding"> |
|||
<el-popover trigger="manual" v-model="conditionBtnVisible" style="float:right;" width="300"> |
|||
<el-button slot="reference" icon="el-icon-more" @click="conditionBtnVisible=!conditionBtnVisible"></el-button> |
|||
<el-row> |
|||
<el-button type="danger" icon="el-icon-delete" @click="doDelete">删除</el-button> |
|||
<el-button style="float:right;" type="text" icon="el-icon-close" @click="conditionBtnVisible=false">关闭</el-button> |
|||
</el-row> |
|||
<el-form :model="filters"> |
|||
<el-form-item label="分组属性"> |
|||
<el-select v-model="groupBy" @change="onXmQuestionSomeFieldsChange('groupBy',$event)" clearable> |
|||
<el-option v-for="i in this.groupBys" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="缺陷状态" prop="bugStatus"> |
|||
<el-select v-model="filters.bugStatus" @change="onXmQuestionSomeFieldsChange('bugStatus',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugStatus" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="缺陷类型" prop="bugType" > |
|||
<el-select v-model="filters.bugType" @change="onXmQuestionSomeFieldsChange('bugType',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugType" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="缺陷原因" prop="bugReason"> |
|||
<el-select v-model="filters.bugReason" @change="onXmQuestionSomeFieldsChange('bugReason',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugReason" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="严重程度" prop="bugSeverity" > |
|||
<el-select v-model="filters.bugSeverity" @change="onXmQuestionSomeFieldsChange('bugSeverity',$event)" clearable> |
|||
<el-option v-for="i in this.dicts.bugSeverity" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="优先级" prop="priority" > |
|||
<el-select v-model="filters.priority" @change="onXmQuestionSomeFieldsChange('priority',$event)" clearable> |
|||
<el-option v-for="i in dicts.priority" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="解决方案" prop="solution" > |
|||
<el-select v-model="filters.solution" @change="onXmQuestionSomeFieldsChange('solution',$event)" clearable> |
|||
<el-option v-for="i in dicts.bugSolution" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="重现频率" prop="repRate" > |
|||
<el-select v-model="filters.repRate" @change="onXmQuestionSomeFieldsChange('repRate',$event)" clearable> |
|||
<el-option v-for="i in dicts.bugRepRate" :label="i.name" :key="i.id" :value="i.id"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<el-button type="primary" icon="el-icon-search" @click="searchXmQuestionSort">查询</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-popover> |
|||
</el-row> |
|||
<el-row > |
|||
<div> |
|||
<div class="main" :id="id" |
|||
style="width:100%;height:600px;margin:0 auto;"></div> |
|||
<div class="progress"></div> |
|||
</div> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '@/common/js/util';//全局公共库 |
|||
import { initSimpleDicts } from '@/api/mdp/meta/item';//下拉框数据查询 |
|||
import { mapGetters } from 'vuex' |
|||
|
|||
import { getXmQuestionSort } from '@/api/xm/core/xmQuestion'; |
|||
|
|||
import XmIterationSelect from '@/views/xm/core/components/XmIterationSelect.vue';//修改界面 |
|||
import XmProductSelect from '@/views/xm/core/components/XmProductSelect';//新增界面 |
|||
|
|||
export default { |
|||
|
|||
components: { |
|||
XmIterationSelect,XmProductSelect, |
|||
}, |
|||
props:['xmTestPlan','compCfg','groupBy'], |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo','roles' |
|||
]), |
|||
xmQuestionSortsCpd(){ |
|||
if(!this.xmQuestionSorts || this.xmQuestionSorts.length==0){ |
|||
return [] |
|||
}else{ |
|||
return this.xmQuestionSorts.map(i=>i.value) |
|||
} |
|||
}, |
|||
title(){ |
|||
return this.compCfg.name |
|||
}, |
|||
legendCpd(){ |
|||
if(!this.xmQuestionSorts || this.xmQuestionSorts.length==0){ |
|||
return [] |
|||
}else{ |
|||
return this.xmQuestionSorts.map(i=>i.name) |
|||
} |
|||
}, |
|||
id(){ |
|||
return this.compCfg.id |
|||
}, |
|||
|
|||
|
|||
}, |
|||
watch: { |
|||
xmQuestionSortsCpd(){ |
|||
this.drawCharts(); |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
filters:{ |
|||
groupBy:'handler_userid', |
|||
}, |
|||
groupBys:[ |
|||
{id:'create_userid', name:'创建人'}, |
|||
{id:'ask_userid', name:'提出人'}, |
|||
{id:'handler_userid', name:'负责人'}, |
|||
{id:'menu_id', name:'故事'}, |
|||
|
|||
], |
|||
dicts:{},//下拉选择框的所有静态数据 params=[{categoryId:'0001',itemCode:'sex'}] 返回结果 {'sex':[{optionValue:'1',optionName:'男',seqOrder:'1',fp:'',isDefault:'0'},{optionValue:'2',optionName:'女',seqOrder:'2',fp:'',isDefault:'0'}]} |
|||
load:{ list: false, edit: false, del: false, add: false },//查询中... |
|||
dateRanger:[], |
|||
maxTableHeight:300, |
|||
visible:false, |
|||
xmQuestionSorts:[], |
|||
conditionBtnVisible:false, |
|||
pageInfo: { |
|||
//分页数据 |
|||
total: 0, //服务器端收到0时,会自动计算总记录数,如果上传>0的不自动计算。 |
|||
pageSize: 20, //每页数据 |
|||
count:true, //是否需要重新计算总记录数 |
|||
pageNum: 1, //当前页码、从1开始计算 |
|||
orderFields: ["value"], //排序列 如 ['sex','student_id'],必须为数据库字段 |
|||
orderDirs: ["desc"], //升序 asc,降序desc 如 性别 升序、学生编号降序 ['asc','desc'] |
|||
}, |
|||
|
|||
}//end return |
|||
},//end data |
|||
methods: { |
|||
drawCharts() { |
|||
this.myChart = this.$echarts.init(document.getElementById(this.id)); |
|||
this.myChart.setOption( |
|||
{ |
|||
title: { |
|||
text: this.title, |
|||
left: 'center' |
|||
}, |
|||
|
|||
tooltip: { |
|||
trigger: 'axis', |
|||
}, |
|||
barMaxWidth: 100, |
|||
toolbox: { |
|||
show: true, |
|||
right:"20px", |
|||
feature: { |
|||
dataView: { show: true, readOnly: false }, |
|||
magicType: { show: true, type: ['line', 'bar'] }, |
|||
|
|||
saveAsImage: { show: true } |
|||
} |
|||
}, |
|||
|
|||
calculable: true, |
|||
xAxis: { |
|||
type: 'category', |
|||
data: this.legendCpd |
|||
}, |
|||
yAxis: { |
|||
type: 'value' |
|||
}, |
|||
series: [ |
|||
{ |
|||
data: this.xmQuestionSortsCpd, |
|||
type: 'bar', |
|||
label:{ |
|||
show: true, |
|||
}, |
|||
} |
|||
] |
|||
} |
|||
) |
|||
}, |
|||
onXmQuestionSomeFieldsChange(fieldName,$event){ |
|||
this.xmQuestionSorts=[] |
|||
}, |
|||
searchXmQuestionSort(){ |
|||
if(!this.filters.groupBy){ |
|||
this.$notify({position:'bottom-left',showClose:true,message:'请选中分组属性',type:'warning'}) |
|||
return |
|||
} |
|||
let params = { |
|||
pageSize: this.pageInfo.pageSize, |
|||
pageNum: this.pageInfo.pageNum, |
|||
total: this.pageInfo.total, |
|||
count: this.pageInfo.count, |
|||
}; |
|||
Object.assign(params,this.filters) |
|||
|
|||
|
|||
if ( |
|||
this.pageInfo.orderFields != null && |
|||
this.pageInfo.orderFields.length > 0 |
|||
) { |
|||
let orderBys = []; |
|||
for (var i = 0; i < this.pageInfo.orderFields.length; i++) { |
|||
orderBys.push( |
|||
this.pageInfo.orderFields[i] + " " + this.pageInfo.orderDirs[i] |
|||
); |
|||
} |
|||
params.orderBy = orderBys.join(","); |
|||
} |
|||
getXmQuestionSort(params).then(res=>{ |
|||
this.xmQuestionSorts=res.data.data |
|||
}) |
|||
|
|||
}, |
|||
onProductSelected(product){ |
|||
this.filters.product=product |
|||
}, |
|||
|
|||
onProductClear(){ |
|||
this.filters.product=null |
|||
|
|||
}, |
|||
|
|||
onIterationSelected(iteration){ |
|||
this.filters.iteration=iteration |
|||
}, |
|||
|
|||
onIterationClear(){ |
|||
this.filters.iteration=null |
|||
} , |
|||
initData(){ |
|||
if(this.groupBy){ |
|||
this.filters.groupBy=this.groupBy |
|||
} |
|||
if(this.xmTestPlan){ |
|||
this.filters.productId=this.xmTestPlan.productId |
|||
this.filters.projectId=this.xmTestPlan.projectId |
|||
this.filters.planId=this.xmTestPlan.id |
|||
} |
|||
|
|||
if(this.compCfg && this.compCfg.params){ |
|||
Object.assign(this.filters,this.compCfg.params) |
|||
} |
|||
}, |
|||
doDelete(){ |
|||
this.$emit("delete",this.compCfg) |
|||
}, |
|||
sizeAutoChange(){ |
|||
this.myChart.resize(); |
|||
} |
|||
},//end method |
|||
mounted() { |
|||
initSimpleDicts('all',['bugSeverity','bugSolution','bugStatus','bugType','priority','bugRepRate','bugReason'] ).then(res=>{ |
|||
this.dicts=res.data.data; |
|||
}) |
|||
this.initData(); |
|||
this.searchXmQuestionSort(); |
|||
//this.charts(); |
|||
//this.drawCharts(); |
|||
|
|||
}//end mounted |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style scoped> |
|||
.image { |
|||
width: 100%; |
|||
display: block; |
|||
} |
|||
</style> |
|||
@ -1,203 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row class="padding"> |
|||
<el-popover trigger="manual" v-model="conditionBtnVisible" style="float:right;" width="300"> |
|||
<el-button slot="reference" icon="el-icon-more" @click="conditionBtnVisible=!conditionBtnVisible"></el-button> |
|||
<el-row> |
|||
<el-button type="danger" icon="el-icon-delete" @click="doDelete">删除</el-button> |
|||
<el-button style="float:right;" type="text" icon="el-icon-close" @click="conditionBtnVisible=false">关闭</el-button> |
|||
</el-row> |
|||
<el-form :model="filters"> |
|||
<el-form-item> |
|||
<el-button type="primary" icon="el-icon-search" @click="searchXmTestCaseToPlanCalcList">查询</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-popover> |
|||
</el-row> |
|||
<el-row> |
|||
<div> |
|||
<div class="main" :id="id" |
|||
style="width:100%;height:600px;margin:0 auto;"></div> |
|||
<div class="progress"></div> |
|||
</div> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '@/common/js/util';//全局公共库 |
|||
import { initSimpleDicts } from '@/api/mdp/meta/item';//下拉框数据查询 |
|||
import { mapGetters } from 'vuex' |
|||
|
|||
import { getXmTestCaseToPlanCalcList } from '@/api/xm/core/xmTestPlanCase'; |
|||
|
|||
export default { |
|||
|
|||
components: { |
|||
}, |
|||
props:['xmTestPlan','xmRptConfig','compCfg'], |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo','roles' |
|||
]), |
|||
xmTestCaseToPlanCalcListCpd(){ |
|||
if(!this.xmTestCaseToPlanCalcList || this.xmTestCaseToPlanCalcList.length==0){ |
|||
return [] |
|||
}else{ |
|||
var names=this.legendCpd; |
|||
var datas=[] |
|||
this.xmTestCaseToPlanCalcList.forEach(i=>{ |
|||
var nameIndex=0; |
|||
if(i.useTimes<=2){ |
|||
nameIndex=i.useTimes |
|||
}else if(i.useTimes>=3 && i.useTimes<=5){ |
|||
nameIndex=3 |
|||
}else if(i.useTimes>5 && i.useTimes<=10){ |
|||
nameIndex=4 |
|||
}else if(i.useTimes>10){ |
|||
nameIndex=5 |
|||
} |
|||
var data={name:names[nameIndex],value:i.caseNum} |
|||
datas.push(data) |
|||
}) |
|||
return datas; |
|||
} |
|||
}, |
|||
title(){ |
|||
return '测试用例规划分析' |
|||
}, |
|||
legendCpd(){ |
|||
return ['0次','1次','2次','3-5次','5-10次','10次以上'] |
|||
}, |
|||
id(){ |
|||
return this.compCfg.id |
|||
}, |
|||
|
|||
}, |
|||
watch: { |
|||
xmTestCaseToPlanCalcListCpd(){ |
|||
this.drawCharts(); |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
filters:{ |
|||
planId:'', |
|||
}, |
|||
|
|||
dicts:{},//下拉选择框的所有静态数据 params=[{categoryId:'0001',itemCode:'sex'}] 返回结果 {'sex':[{optionValue:'1',optionName:'男',seqOrder:'1',fp:'',isDefault:'0'},{optionValue:'2',optionName:'女',seqOrder:'2',fp:'',isDefault:'0'}]} |
|||
load:{ list: false, edit: false, del: false, add: false },//查询中... |
|||
dateRanger:[], |
|||
maxTableHeight:300, |
|||
visible:false, |
|||
xmTestCaseToPlanCalcList:[], |
|||
conditionBtnVisible:false, |
|||
|
|||
}//end return |
|||
},//end data |
|||
methods: { |
|||
formatDict(itemId,val){ |
|||
var dict=this.dicts[itemId] |
|||
if(dict){ |
|||
var item=dict.find(i=>i.id==val) |
|||
if(item){ |
|||
return item.name |
|||
} |
|||
} |
|||
return val; |
|||
}, |
|||
drawCharts() { |
|||
this.myChart = this.$echarts.init(document.getElementById(this.id)); |
|||
this.myChart.setOption( |
|||
{ |
|||
title: { |
|||
text: this.title, |
|||
left: 'center' |
|||
}, |
|||
tooltip: { |
|||
trigger: 'item', |
|||
|
|||
}, |
|||
|
|||
toolbox: { |
|||
show: true, |
|||
right:"20px", |
|||
feature: { |
|||
dataView: { show: true, readOnly: false }, |
|||
saveAsImage: { show: true }, |
|||
} |
|||
}, |
|||
calculable: true, |
|||
|
|||
legend: { |
|||
top:'5%', |
|||
left: 'center', |
|||
data:this.legendCpd, |
|||
}, |
|||
series: [ |
|||
{ |
|||
type: 'pie', |
|||
radius: '50%', |
|||
data: this.xmTestCaseToPlanCalcListCpd, |
|||
emphasis: { |
|||
itemStyle: { |
|||
shadowBlur: 10, |
|||
shadowOffsetX: 0, |
|||
shadowColor: 'rgba(0, 0, 0, 0.5)' |
|||
} |
|||
}, |
|||
|
|||
label: { |
|||
show: true, |
|||
formatter:'{b}: {c} ({d}%)' |
|||
}, |
|||
} |
|||
] |
|||
} |
|||
) |
|||
}, |
|||
onXmQuestionSomeFieldsChange(fieldName,$event){ |
|||
this.xmTestCaseToPlanCalcList=[] |
|||
}, |
|||
searchXmTestCaseToPlanCalcList(){ |
|||
var params={...this.filters} |
|||
getXmTestCaseToPlanCalcList(params).then(res=>{ |
|||
this.xmTestCaseToPlanCalcList=res.data.data |
|||
}) |
|||
|
|||
}, |
|||
initData(){ |
|||
if(this.xmTestPlan){ |
|||
this.filters.productId=this.xmTestPlan.productId |
|||
this.filters.projectId=this.xmTestPlan.projectId |
|||
this.filters.planId=this.xmTestPlan.id |
|||
} |
|||
|
|||
if(this.compCfg && this.compCfg.params){ |
|||
Object.assign(this.filters,this.compCfg.params) |
|||
} |
|||
}, |
|||
doDelete(){ |
|||
this.$emit("delete",this.compCfg) |
|||
}, |
|||
sizeAutoChange(){ |
|||
this.myChart.resize(); |
|||
} |
|||
},//end method |
|||
mounted() { |
|||
this.initData(); |
|||
this.searchXmTestCaseToPlanCalcList(); |
|||
//this.charts(); |
|||
//this.drawCharts(); |
|||
|
|||
}//end mounted |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style scoped> |
|||
.image { |
|||
width: 100%; |
|||
display: block; |
|||
} |
|||
</style> |
|||
@ -1,188 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row class="padding"> |
|||
<el-popover trigger="manual" v-model="conditionBtnVisible" style="float:right;" width="300"> |
|||
<el-button slot="reference" icon="el-icon-more" @click="conditionBtnVisible=!conditionBtnVisible"></el-button> |
|||
<el-row> |
|||
<el-button type="danger" icon="el-icon-delete" @click="doDelete">删除</el-button> |
|||
<el-button style="float:right;" type="text" icon="el-icon-close" @click="conditionBtnVisible=false">关闭</el-button> |
|||
</el-row> |
|||
<el-form :model="filters"> |
|||
<el-form-item> |
|||
<el-button type="primary" icon="el-icon-search" @click="searchXmTestDayTimesList">查询</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-popover> |
|||
</el-row> |
|||
<el-row> |
|||
<div> |
|||
<div class="main" :id="id" |
|||
style="width:100%;height:600px;margin:0 auto;"></div> |
|||
<div class="progress"></div> |
|||
</div> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '@/common/js/util';//全局公共库 |
|||
import { mapGetters } from 'vuex' |
|||
|
|||
import { getXmTestDayTimesList } from '@/api/xm/core/xmTestPlanCase'; |
|||
|
|||
export default { |
|||
|
|||
components: { |
|||
}, |
|||
props:['xmTestPlan','xmRptConfig','compCfg'], |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo','roles' |
|||
]), |
|||
datesCpd(){ |
|||
if(!this.xmTestDayTimesList || this.xmTestDayTimesList.length==0){ |
|||
return [] |
|||
}else{ |
|||
return this.xmTestDayTimesList.map(i=>i.execDate) |
|||
} |
|||
}, |
|||
testDayTimesCpd(){ |
|||
if(!this.xmTestDayTimesList || this.xmTestDayTimesList.length==0){ |
|||
return [] |
|||
}else{ |
|||
return this.xmTestDayTimesList.map(i=>i.hadExec) |
|||
} |
|||
}, |
|||
|
|||
title(){ |
|||
return '测试用例每日执行次数统计' |
|||
}, |
|||
id(){ |
|||
return this.compCfg.id |
|||
}, |
|||
|
|||
}, |
|||
watch: { |
|||
testDayTimesCpd(){ |
|||
this.drawCharts(); |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
filters:{ |
|||
planId:'', |
|||
}, |
|||
|
|||
dicts:{},//下拉选择框的所有静态数据 params=[{categoryId:'0001',itemCode:'sex'}] 返回结果 {'sex':[{optionValue:'1',optionName:'男',seqOrder:'1',fp:'',isDefault:'0'},{optionValue:'2',optionName:'女',seqOrder:'2',fp:'',isDefault:'0'}]} |
|||
load:{ list: false, edit: false, del: false, add: false },//查询中... |
|||
dateRanger:[], |
|||
maxTableHeight:300, |
|||
visible:false, |
|||
xmTestDayTimesList:[], |
|||
conditionBtnVisible:false, |
|||
|
|||
}//end return |
|||
},//end data |
|||
methods: { |
|||
formatDict(itemId,val){ |
|||
var dict=this.dicts[itemId] |
|||
if(dict){ |
|||
var item=dict.find(i=>i.id==val) |
|||
if(item){ |
|||
return item.name |
|||
} |
|||
} |
|||
return val; |
|||
}, |
|||
drawCharts() { |
|||
this.myChart = this.$echarts.init(document.getElementById(this.id)); |
|||
this.myChart.setOption( |
|||
{ |
|||
title: { |
|||
text: this.title, |
|||
left: 'center' |
|||
}, |
|||
|
|||
tooltip: { |
|||
trigger: 'axis', |
|||
}, |
|||
barMaxWidth: 100, |
|||
toolbox: { |
|||
show: true, |
|||
right:"20px", |
|||
feature: { |
|||
dataView: { show: true, readOnly: false }, |
|||
magicType: { show: true, type: ['line', 'bar'] }, |
|||
|
|||
saveAsImage: { show: true } |
|||
} |
|||
}, |
|||
|
|||
calculable: true, |
|||
xAxis: { |
|||
type: 'category', |
|||
data: this.datesCpd |
|||
}, |
|||
yAxis: { |
|||
type: 'value' |
|||
}, |
|||
series: [ |
|||
{ |
|||
name:'次数', |
|||
data: this.testDayTimesCpd, |
|||
type: 'line', |
|||
label:{ |
|||
show: true, |
|||
}, |
|||
smooth: true, |
|||
} |
|||
] |
|||
} |
|||
) |
|||
}, |
|||
onXmQuestionSomeFieldsChange(fieldName,$event){ |
|||
this.xmTestDayTimesList=[] |
|||
}, |
|||
searchXmTestDayTimesList(){ |
|||
var params={...this.filters} |
|||
getXmTestDayTimesList(params).then(res=>{ |
|||
this.xmTestDayTimesList=res.data.data |
|||
}) |
|||
|
|||
}, |
|||
initData(){ |
|||
if(this.xmTestPlan){ |
|||
this.filters.productId=this.xmTestPlan.productId |
|||
this.filters.projectId=this.xmTestPlan.projectId |
|||
this.filters.planId=this.xmTestPlan.id |
|||
} |
|||
|
|||
if(this.compCfg && this.compCfg.params){ |
|||
Object.assign(this.filters,this.compCfg.params) |
|||
} |
|||
this.drawCharts(); |
|||
}, |
|||
doDelete(){ |
|||
this.$emit("delete",this.compCfg) |
|||
}, |
|||
sizeAutoChange(){ |
|||
this.myChart.resize(); |
|||
} |
|||
},//end method |
|||
mounted() { |
|||
this.initData(); |
|||
this.searchXmTestDayTimesList(); |
|||
//this.charts(); |
|||
//this.drawCharts(); |
|||
|
|||
}//end mounted |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style scoped> |
|||
.image { |
|||
width: 100%; |
|||
display: block; |
|||
} |
|||
</style> |
|||
@ -1,222 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row class="padding"> |
|||
<el-popover trigger="manual" v-model="conditionBtnVisible" style="float:right;" width="300"> |
|||
<el-button slot="reference" icon="el-icon-more" @click="conditionBtnVisible=!conditionBtnVisible"></el-button> |
|||
<el-row> |
|||
<el-button type="danger" icon="el-icon-delete" @click="doDelete">删除</el-button> |
|||
<el-button style="float:right;" type="text" icon="el-icon-close" @click="conditionBtnVisible=false">关闭</el-button> |
|||
</el-row> |
|||
<el-form :model="filters"> |
|||
<el-form-item> |
|||
<el-button type="primary" icon="el-icon-search" @click="searchXmTestPlanCaseExecStatusDist">查询</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-popover> |
|||
</el-row> |
|||
<el-row> |
|||
<div> |
|||
<div class="main" :id="id" |
|||
style="width:100%;height:600px;margin:0 auto;"></div> |
|||
<div class="progress"></div> |
|||
</div> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '@/common/js/util';//全局公共库 |
|||
import { initSimpleDicts } from '@/api/mdp/meta/item';//下拉框数据查询 |
|||
import { mapGetters } from 'vuex' |
|||
|
|||
import { getXmTestPlanCaseExecStatusDist } from '@/api/xm/core/xmTestPlanCase'; |
|||
|
|||
import XmIterationSelect from '@/views/xm/core/components/XmIterationSelect.vue';//修改界面 |
|||
import XmProductSelect from '@/views/xm/core/components/XmProductSelect';//新增界面 |
|||
|
|||
export default { |
|||
|
|||
components: { |
|||
XmIterationSelect,XmProductSelect, |
|||
}, |
|||
props:['xmTestPlan','xmRptConfig','compCfg'], |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo','roles' |
|||
]), |
|||
xmTestPlanCaseExecStatusDistsCpd(){ |
|||
if(!this.xmTestPlanCaseExecStatusDists || this.xmTestPlanCaseExecStatusDists.length==0){ |
|||
return [] |
|||
}else{ |
|||
var datas=[] |
|||
this.xmTestPlanCaseExecStatusDists.forEach(i=>{ |
|||
var data={} |
|||
var itemId="testStepTcode"; |
|||
data.name=this.formatDict(itemId,i.execStatus) |
|||
data.value=i.totalCnt |
|||
datas.push(data) |
|||
}) |
|||
return datas; |
|||
} |
|||
}, |
|||
title(){ |
|||
var preName="" |
|||
return preName+ '测试用例执行结果数量分布' |
|||
}, |
|||
/**0-未测,1-通过,2-受阻,3-忽略,4-失败 */ |
|||
legendCpd(){ |
|||
var itemId="testStepTcode"; |
|||
return this.dicts[itemId].map(i=>this.formatDict(itemId,i.id)) |
|||
}, |
|||
id(){ |
|||
return this.compCfg.id |
|||
}, |
|||
|
|||
}, |
|||
watch: { |
|||
xmTestPlanCaseExecStatusDistsCpd(){ |
|||
this.drawCharts(); |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
filters:{ |
|||
planId:'', |
|||
}, |
|||
|
|||
dicts:{testStepTcode:[]},//下拉选择框的所有静态数据 params=[{categoryId:'0001',itemCode:'sex'}] 返回结果 {'sex':[{optionValue:'1',optionName:'男',seqOrder:'1',fp:'',isDefault:'0'},{optionValue:'2',optionName:'女',seqOrder:'2',fp:'',isDefault:'0'}]} |
|||
load:{ list: false, edit: false, del: false, add: false },//查询中... |
|||
dateRanger:[], |
|||
maxTableHeight:300, |
|||
visible:false, |
|||
xmTestPlanCaseExecStatusDists:[], |
|||
conditionBtnVisible:false, |
|||
|
|||
}//end return |
|||
},//end data |
|||
methods: { |
|||
formatDict(itemId,val){ |
|||
var dict=this.dicts[itemId] |
|||
if(dict){ |
|||
var item=dict.find(i=>i.id==val) |
|||
if(item){ |
|||
return item.name |
|||
} |
|||
} |
|||
return val; |
|||
}, |
|||
drawCharts() { |
|||
this.myChart = this.$echarts.init(document.getElementById(this.id)); |
|||
this.myChart.setOption( |
|||
{ |
|||
title: { |
|||
text: this.title, |
|||
left: 'center' |
|||
}, |
|||
tooltip: { |
|||
trigger: 'item', |
|||
|
|||
}, |
|||
|
|||
toolbox: { |
|||
show: true, |
|||
right:"20px", |
|||
feature: { |
|||
dataView: { show: true, readOnly: false }, |
|||
saveAsImage: { show: true }, |
|||
} |
|||
}, |
|||
calculable: true, |
|||
|
|||
legend: { |
|||
top:'5%', |
|||
left: 'center', |
|||
data:this.legendCpd, |
|||
}, |
|||
series: [ |
|||
{ |
|||
type: 'pie', |
|||
radius: '50%', |
|||
data: this.xmTestPlanCaseExecStatusDistsCpd, |
|||
emphasis: { |
|||
itemStyle: { |
|||
shadowBlur: 10, |
|||
shadowOffsetX: 0, |
|||
shadowColor: 'rgba(0, 0, 0, 0.5)' |
|||
} |
|||
}, |
|||
|
|||
label: { |
|||
show: true, |
|||
formatter:'{b}: {c} ({d}%)' |
|||
|
|||
}, |
|||
} |
|||
] |
|||
} |
|||
) |
|||
}, |
|||
onXmQuestionSomeFieldsChange(fieldName,$event){ |
|||
this.xmTestPlanCaseExecStatusDists=[] |
|||
}, |
|||
searchXmTestPlanCaseExecStatusDist(){ |
|||
var params={...this.filters} |
|||
getXmTestPlanCaseExecStatusDist(params).then(res=>{ |
|||
this.xmTestPlanCaseExecStatusDists=res.data.data |
|||
}) |
|||
|
|||
}, |
|||
onProductSelected(product){ |
|||
this.filters.product=product |
|||
}, |
|||
|
|||
onProductClear(){ |
|||
this.filters.product=null |
|||
|
|||
}, |
|||
|
|||
onIterationSelected(iteration){ |
|||
this.filters.iteration=iteration |
|||
}, |
|||
|
|||
onIterationClear(){ |
|||
this.filters.iteration=null |
|||
}, |
|||
initData(){ |
|||
if(this.xmTestPlan){ |
|||
this.filters.productId=this.xmTestPlan.productId |
|||
this.filters.projectId=this.xmTestPlan.projectId |
|||
this.filters.planId=this.xmTestPlan.id |
|||
} |
|||
|
|||
if(this.compCfg && this.compCfg.params){ |
|||
Object.assign(this.filters,this.compCfg.params) |
|||
} |
|||
}, |
|||
doDelete(){ |
|||
this.$emit("delete",this.compCfg) |
|||
}, |
|||
sizeAutoChange(){ |
|||
this.myChart.resize(); |
|||
} |
|||
},//end method |
|||
mounted() { |
|||
initSimpleDicts('all',['testStepTcode'] ).then(res=>{ |
|||
this.dicts=res.data.data; |
|||
}) |
|||
this.initData(); |
|||
this.searchXmTestPlanCaseExecStatusDist(); |
|||
//this.charts(); |
|||
//this.drawCharts(); |
|||
|
|||
}//end mounted |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style scoped> |
|||
.image { |
|||
width: 100%; |
|||
display: block; |
|||
} |
|||
</style> |
|||
@ -1,249 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row class="padding"> |
|||
<el-popover trigger="manual" v-model="conditionBtnVisible" style="float:right;" width="300"> |
|||
<el-button slot="reference" icon="el-icon-more" @click="conditionBtnVisible=!conditionBtnVisible"></el-button> |
|||
<el-row> |
|||
<el-button type="danger" icon="el-icon-delete" @click="doDelete">删除</el-button> |
|||
<el-button style="float:right;" type="text" icon="el-icon-close" @click="conditionBtnVisible=false">关闭</el-button> |
|||
</el-row> |
|||
<el-form :model="filters"> |
|||
<el-form-item> |
|||
<el-button type="primary" icon="el-icon-search" @click="searchXmTestPlanCaseUserDist">查询</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-popover> |
|||
</el-row> |
|||
<el-row> |
|||
<div> |
|||
<div class="main" :id="id" |
|||
style="width:100%;height:600px;margin:0 auto;"></div> |
|||
<div class="progress"></div> |
|||
</div> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '@/common/js/util';//全局公共库 |
|||
import { initSimpleDicts } from '@/api/mdp/meta/item';//下拉框数据查询 |
|||
import { mapGetters } from 'vuex' |
|||
|
|||
import { getXmTestPlanCaseUserDist } from '@/api/xm/core/xmTestPlanCase'; |
|||
|
|||
import XmIterationSelect from '@/views/xm/core/components/XmIterationSelect.vue';//修改界面 |
|||
import XmProductSelect from '@/views/xm/core/components/XmProductSelect';//新增界面 |
|||
|
|||
export default { |
|||
|
|||
components: { |
|||
XmIterationSelect,XmProductSelect, |
|||
}, |
|||
props:['xmTestPlan','xmRptConfig','compCfg'], |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo','roles' |
|||
]), |
|||
|
|||
hadExecCpd(){ |
|||
if(!this.xmTestPlanCaseUserDists ||this.xmTestPlanCaseUserDists.length==0){ |
|||
return [] |
|||
}else{ |
|||
return this.xmTestPlanCaseUserDists.map(i=>i.hadExec) |
|||
} |
|||
}, |
|||
|
|||
notExecCpd(){ |
|||
if(!this.xmTestPlanCaseUserDists ||this.xmTestPlanCaseUserDists.length==0){ |
|||
return [] |
|||
}else{ |
|||
return this.xmTestPlanCaseUserDists.map(i=>i.notExec) |
|||
} |
|||
}, |
|||
legendCpd(){ |
|||
if(!this.xmTestPlanCaseUserDists ||this.xmTestPlanCaseUserDists.length==0){ |
|||
return [] |
|||
}else{ |
|||
return this.xmTestPlanCaseUserDists.map(i=>i.execUsername) |
|||
} |
|||
|
|||
}, |
|||
xmTestPlanCaseUserDistsCpd(){ |
|||
if(!this.xmTestPlanCaseUserDists || this.xmTestPlanCaseUserDists.length==0){ |
|||
return [] |
|||
}else{ |
|||
var datas=[] |
|||
this.xmTestPlanCaseUserDists.forEach(i=>{ |
|||
var data={} |
|||
var itemId="testPlanTcode"; |
|||
data.name=this.formatDict(itemId,i.execStatus) |
|||
data.value=i.totalCnt |
|||
datas.push(data) |
|||
}) |
|||
return datas; |
|||
} |
|||
}, |
|||
title(){ |
|||
var preName="" |
|||
return preName+ '测试用例按执行人分组统计' |
|||
}, |
|||
id(){ |
|||
return this.compCfg.id |
|||
}, |
|||
|
|||
}, |
|||
watch: { |
|||
xmTestPlanCaseUserDistsCpd(){ |
|||
this.drawCharts(); |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
filters:{ |
|||
planId:'', |
|||
}, |
|||
|
|||
dicts:{},//下拉选择框的所有静态数据 params=[{categoryId:'0001',itemCode:'sex'}] 返回结果 {'sex':[{optionValue:'1',optionName:'男',seqOrder:'1',fp:'',isDefault:'0'},{optionValue:'2',optionName:'女',seqOrder:'2',fp:'',isDefault:'0'}]} |
|||
load:{ list: false, edit: false, del: false, add: false },//查询中... |
|||
dateRanger:[], |
|||
maxTableHeight:300, |
|||
visible:false, |
|||
xmTestPlanCaseUserDists:[], |
|||
conditionBtnVisible:false, |
|||
|
|||
}//end return |
|||
},//end data |
|||
methods: { |
|||
formatDict(itemId,val){ |
|||
var dict=this.dicts[itemId] |
|||
if(dict){ |
|||
var item=dict.find(i=>i.id==val) |
|||
if(item){ |
|||
return item.name |
|||
} |
|||
} |
|||
return val; |
|||
}, |
|||
drawCharts() { |
|||
this.myChart = this.$echarts.init(document.getElementById(this.id)); |
|||
this.myChart.setOption( |
|||
{ |
|||
title: { |
|||
text: this.title, |
|||
left: 'center' |
|||
}, |
|||
|
|||
tooltip: { |
|||
trigger: 'item', |
|||
}, |
|||
barMaxWidth: 100, |
|||
toolbox: { |
|||
show: true, |
|||
right:"20px", |
|||
feature: { |
|||
dataView: { show: true, readOnly: false }, |
|||
magicType: { show: true, type: ['line', 'bar'] }, |
|||
|
|||
saveAsImage: { show: true } |
|||
} |
|||
}, |
|||
|
|||
calculable: true, |
|||
|
|||
legend: { |
|||
top:'5%', |
|||
left: 'center', |
|||
data: ['已执行', '未执行'] |
|||
}, |
|||
xAxis: { |
|||
type: 'category', |
|||
data: this.legendCpd |
|||
}, |
|||
yAxis: { |
|||
type: 'value' |
|||
}, |
|||
series: [ |
|||
{ |
|||
name: '已执行', |
|||
type: 'bar', |
|||
data: this.hadExecCpd, |
|||
label:{ |
|||
show: true, |
|||
}, |
|||
}, |
|||
{ |
|||
name: '未执行', |
|||
type: 'bar', |
|||
data: this.notExecCpd, |
|||
label:{ |
|||
show: true, |
|||
}, |
|||
}, |
|||
] |
|||
} |
|||
) |
|||
}, |
|||
onXmQuestionSomeFieldsChange(fieldName,$event){ |
|||
this.xmTestPlanCaseUserDists=[] |
|||
}, |
|||
searchXmTestPlanCaseUserDist(){ |
|||
var params={...this.filters} |
|||
getXmTestPlanCaseUserDist(params).then(res=>{ |
|||
this.xmTestPlanCaseUserDists=res.data.data |
|||
}) |
|||
|
|||
}, |
|||
onProductSelected(product){ |
|||
this.filters.product=product |
|||
}, |
|||
|
|||
onProductClear(){ |
|||
this.filters.product=null |
|||
|
|||
}, |
|||
|
|||
onIterationSelected(iteration){ |
|||
this.filters.iteration=iteration |
|||
}, |
|||
|
|||
onIterationClear(){ |
|||
this.filters.iteration=null |
|||
}, |
|||
initData(){ |
|||
if(this.xmTestPlan){ |
|||
this.filters.productId=this.xmTestPlan.productId |
|||
this.filters.projectId=this.xmTestPlan.projectId |
|||
this.filters.planId=this.xmTestPlan.id |
|||
} |
|||
|
|||
if(this.compCfg && this.compCfg.params){ |
|||
Object.assign(this.filters,this.compCfg.params) |
|||
} |
|||
}, |
|||
doDelete(){ |
|||
this.$emit("delete",this.compCfg) |
|||
}, |
|||
sizeAutoChange(){ |
|||
this.myChart.resize(); |
|||
} |
|||
},//end method |
|||
mounted() { |
|||
initSimpleDicts('all',['testPlanTcode'] ).then(res=>{ |
|||
this.dicts=res.data.data; |
|||
}) |
|||
this.initData(); |
|||
this.searchXmTestPlanCaseUserDist(); |
|||
//this.charts(); |
|||
//this.drawCharts(); |
|||
|
|||
}//end mounted |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style scoped> |
|||
.image { |
|||
width: 100%; |
|||
display: block; |
|||
} |
|||
</style> |
|||
@ -1,10 +0,0 @@ |
|||
.m_container { |
|||
width: 100%; |
|||
height: 100%; |
|||
background: rgb(238, 238, 238); |
|||
.m_content { |
|||
padding:30px 18px 18px 18px; |
|||
overflow: hidden; |
|||
position: relative; |
|||
} |
|||
} |
|||
|
Before Width: 600 | Height: 450 | Size: 104 KiB |
|
Before Width: 600 | Height: 450 | Size: 63 KiB |
|
Before Width: 600 | Height: 450 | Size: 146 KiB |
|
Before Width: 600 | Height: 450 | Size: 91 KiB |
|
Before Width: 600 | Height: 450 | Size: 60 KiB |
|
Before Width: 842 | Height: 579 | Size: 42 KiB |
@ -1,98 +0,0 @@ |
|||
.m_top { |
|||
background: #fff; |
|||
display: flex; |
|||
flex-direction: row; |
|||
height: 100px; |
|||
align-items: center; |
|||
border: 1px solid #ebeef5; |
|||
margin: 0 10px; |
|||
.m_avatar { |
|||
width: 52px; |
|||
height: 52px; |
|||
margin-left: 34px; |
|||
} |
|||
.m_msg { |
|||
margin-left: 22px; |
|||
p:nth-child(1) { |
|||
font-size: 20px; |
|||
font-weight: bold; |
|||
color: #7D7D7D; |
|||
opacity: 0.92; |
|||
} |
|||
p:nth-child(2) { |
|||
margin-top: 12px; |
|||
font-size: 14px; |
|||
font-weight: bold; |
|||
color: #7D7D7D; |
|||
opacity: 0.53; |
|||
} |
|||
} |
|||
.m_btn { |
|||
margin-left: auto; |
|||
margin-right: 20px; |
|||
} |
|||
} |
|||
|
|||
|
|||
.m_middle { |
|||
display: flex; |
|||
flex-direction: row; |
|||
margin-top: 20px; |
|||
height: 280px; |
|||
.m_left, .m_right { |
|||
flex: 1; |
|||
padding: 30px; |
|||
background: #fff; |
|||
border: 1px solid #ebeef5; |
|||
} |
|||
.m_left { |
|||
display: flex; |
|||
flex-direction: row; |
|||
margin-right: 10px; |
|||
margin-left: 10px; |
|||
.m_left_1 { |
|||
flex: 1.5; |
|||
p { |
|||
font-size: 18px; |
|||
margin-bottom: 20px; |
|||
} |
|||
span { |
|||
font-size: 15px; |
|||
line-height: 42px; |
|||
color: #7D7D7D; |
|||
} |
|||
} |
|||
.m_left_2 { |
|||
flex: 1; |
|||
img { |
|||
width: 100%; |
|||
margin-left: 20px; |
|||
margin-top: 10px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.m_right { |
|||
display: flex; |
|||
flex-direction: row; |
|||
flex-wrap: wrap; |
|||
margin-right: 10px; |
|||
.m_right_menu { |
|||
display: flex; |
|||
width: 33.3%; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
font-size: 16px; |
|||
cursor: pointer; |
|||
img { |
|||
width: 58px; |
|||
height: 58px; |
|||
} |
|||
span { |
|||
margin-top: 12px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -1,58 +0,0 @@ |
|||
<template> |
|||
<section> |
|||
<el-row v-if="rptConfigVisible"> |
|||
<span style="float:right;"> <el-button @click="rptConfigVisible=false">取消配置</el-button><el-button @click="saveXmRptConfig" type="primary">保存配置</el-button></span> |
|||
</el-row> |
|||
<el-row> |
|||
<comps-card ref="compsCard" :xm-test-plan="xmTestPlan" :rpt-config-visible="rptConfigVisible"/> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
import NProgress from 'nprogress' // progress bar |
|||
|
|||
import compsCard from './CompsCard' |
|||
import compsSet from './CompsSet' |
|||
import { mapGetters } from 'vuex' |
|||
import dayjs from 'dayjs' |
|||
|
|||
export default { |
|||
props:['xmTestPlan'], |
|||
components: {compsSet, compsCard}, |
|||
computed: { |
|||
...mapGetters([ |
|||
'userInfo' |
|||
]), |
|||
}, |
|||
|
|||
watch: { |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
rptConfigVisible:false, |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
saveXmRptConfig(){ |
|||
var callback=()=>{ |
|||
this.rptConfigVisible=false; |
|||
} |
|||
this.$refs['compsCard'].submitXmPrtConfig(callback) |
|||
}, |
|||
showPrint(){ |
|||
this.$refs.compsCard.printVisible=true; |
|||
} |
|||
}, |
|||
|
|||
|
|||
mounted() { |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
</style> |
|||
@ -0,0 +1,407 @@ |
|||
<template> |
|||
<section class="padding"> |
|||
<el-row class="padding-bottom"> |
|||
<span>报告概览</span> |
|||
</el-row> |
|||
<el-row ref="table"> |
|||
<el-row class="box"> |
|||
<el-col :span="6" class="box-red"> |
|||
<div class="box-info"> |
|||
<div class="num">{{xmTestPlan.totalCases?xmTestPlan.totalCases:'0'}}个</div> |
|||
<div class="label">用例数</div> |
|||
</div> |
|||
</el-col> |
|||
<el-col :span="6" class="box-blue"> |
|||
<div class="box-info"> |
|||
<div class="num">{{caseFuGaiLv}}%</div> |
|||
<div class="label">用例覆盖率</div> |
|||
</div> |
|||
</el-col> |
|||
<el-col :span="6" class="box-green"> |
|||
<div class="box-info"> |
|||
<div class="num">{{caseTongGuoLv}}%</div> |
|||
<div class="label">用例通过率</div> |
|||
</div> |
|||
</el-col> |
|||
<el-col :span="6" class="box-orange"> |
|||
<div class="box-info"> |
|||
<div class="num">{{xmTestPlan.bugCnt?xmTestPlan.bugCnt:0}}个</div> |
|||
<div class="label">缺陷数</div> |
|||
</div> |
|||
</el-col> |
|||
</el-row> |
|||
<!--编辑界面 XmTestPlan 测试计划--> |
|||
<el-form :model="rawDatas" label-width="120px" :rules="rawDatasRules" ref="rawDatasRef" label-position="left"> |
|||
<el-form-item prop="name" label-width="0px"> |
|||
<el-row class="padding-bottom"> |
|||
<my-input v-model="rawDatas.name" placeholder="计划名称" :maxlength="255" @change="editSomeFields(rawDatas,'name',$event)"></my-input> |
|||
</el-row> |
|||
</el-form-item> |
|||
<el-row class="padding"> |
|||
<el-col :span="8"> |
|||
<mdp-select-user-xm label="负责人" userid-key="cuserid" username-key="cusername" v-model="rawDatas" @change="editSomeFields(rawDatas,'cuserid',$event)"></mdp-select-user-xm> |
|||
</el-col> |
|||
<el-col :span="8"> |
|||
<mdp-select-dict-x label="状态" :dict="dicts['testPlanStatus']" v-model="rawDatas.status" @change="editSomeFields(rawDatas,'status',$event)"></mdp-select-dict-x> |
|||
</el-col> |
|||
|
|||
<el-col :span="8"> |
|||
<mdp-select-dict-x label="测试结果" :dict="dicts['testPlanTcode']" v-model="rawDatas.tcode" @change="editSomeFields(rawDatas,'tcode',$event)"></mdp-select-dict-x> |
|||
</el-col> |
|||
</el-row> |
|||
<el-form-item label="归属测试库" prop="casedbName"> |
|||
{{rawDatas.casedbName}} |
|||
</el-form-item> |
|||
<el-form-item label="归属项目" prop="projectId"> |
|||
|
|||
<span v-if="opType=='add'"> |
|||
<xm-project-select v-if="!selProject || !selProject.id" ref="xmProjectSelect" :link-product-id="xmTestCasedb? xmTestCasedb.productId:null" @row-click="onPorjectConfirm" :auto-select="false"> |
|||
<span slot="title">选择项目</span> |
|||
</xm-project-select> |
|||
<div v-else>{{rawDatas.projectName}}</div> |
|||
</span> |
|||
<div v-else>{{rawDatas.projectName}}</div> |
|||
</el-form-item> |
|||
<el-form-item label="归属产品" prop="productName"> |
|||
{{rawDatas.productName}} |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="起止时间" prop="stime"> |
|||
<mdp-date-range :auto-default="false" placeholder="选择日期" v-model="rawDatas" start-key="stime" end-key="etime" value-format="yyyy-MM-dd HH:mm:ss" format="yyyy-MM-dd" @change="editSomeFields(rawDatas,'stime',rawDatas)"></mdp-date-range> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-row> |
|||
<el-row class="padding-bottom"> |
|||
<span>报告总结</span> |
|||
</el-row> |
|||
<el-row> |
|||
<el-input type="textarea" :rows="8" v-model="rawDatas.summaryRemark"></el-input> |
|||
</el-row> |
|||
<el-row v-if="rawDatas.summaryRemark!==rawDatasBak.summaryRemark" > |
|||
<span style="float:right;"> |
|||
<el-button type="primary" @click.native="editSomeFields(rawDatas,'summaryRemark',rawDatas.summaryRemark)">提交</el-button> |
|||
</span> |
|||
</el-row> |
|||
</section> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '@/common/js/util';//全局公共库 |
|||
import config from "@/common/config"; //全局公共库import |
|||
import { initDicts, addXmTestPlan,editXmTestPlan,editSomeFieldsXmTestPlan } from '@/api/xm/core/xmTestPlan'; |
|||
import { mapGetters } from 'vuex' |
|||
import XmProjectSelect from '@/views/xm/core/components/XmProjectSelect'; |
|||
|
|||
import MdpSelectUserXm from '@/views/xm/core/components/MdpSelectUserXm';//修改界面 |
|||
export default { |
|||
name:'xmTestPlanEdit', |
|||
components: { |
|||
XmProjectSelect,MdpSelectUserXm, |
|||
}, |
|||
computed: { |
|||
...mapGetters([ 'userInfo' ]), |
|||
caseFuGaiLv(){ |
|||
if(!this.xmTestPlan.totalCases){ |
|||
return 0 |
|||
} |
|||
var okCases=parseInt(this.xmTestPlan.okCases>0?this.xmTestPlan.okCases:0) |
|||
var errCases=parseInt(this.xmTestPlan.errCases>0?this.xmTestPlan.errCases:0) |
|||
var igCases=parseInt(this.xmTestPlan.igCases>0?this.xmTestPlan.igCases:0) |
|||
var blCases=parseInt(this.xmTestPlan.blCases>0?this.xmTestPlan.blCases:0) |
|||
var totalExecs=okCases+errCases+igCases+blCases |
|||
var rate=parseInt(totalExecs/this.xmTestPlan.totalCases*100) |
|||
return rate; |
|||
}, |
|||
caseTongGuoLv(){ |
|||
if(!this.xmTestPlan.totalCases){ |
|||
return 0 |
|||
} |
|||
var okCases=parseInt(this.xmTestPlan.okCases>0?this.xmTestPlan.okCases:0) |
|||
var errCases=parseInt(this.xmTestPlan.errCases>0?this.xmTestPlan.errCases:0) |
|||
var igCases=parseInt(this.xmTestPlan.igCases>0?this.xmTestPlan.igCases:0) |
|||
var blCases=parseInt(this.xmTestPlan.blCases>0?this.xmTestPlan.blCases:0) |
|||
var totalExecs=okCases+igCases |
|||
var rate=parseInt(totalExecs/this.xmTestPlan.totalCases*100) |
|||
return rate; |
|||
} |
|||
|
|||
}, |
|||
props:['xmTestPlan','visible','opType','selProject','xmTestCasedb','rptDatas'], |
|||
|
|||
watch: { |
|||
'xmTestPlan':function( xmTestPlan ) { |
|||
if(xmTestPlan){ |
|||
this.rawDatas = {...xmTestPlan}; |
|||
} |
|||
|
|||
}, |
|||
'visible':function(visible) { |
|||
if(visible==true){ |
|||
this.initData() |
|||
} |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
currOpType:'add',//add/edit |
|||
load:{ list: false, edit: false, del: false, add: false },//查询中... |
|||
dicts:{ |
|||
testPlanStatus:[], |
|||
testPlanTcode:[], |
|||
|
|||
},//下拉选择框的所有静态数据 params={categoryId:'all',itemCodes:['sex']} 返回结果 {sex: [{id:'1',name:'男'},{id:'2',name:'女'}]} |
|||
rawDatasRules: { |
|||
|
|||
}, |
|||
rawDatas: { |
|||
id:'',name:'',casedbId:'',casedbName:'',projectId:'',projectName:'',cuserid:'',cusername:'',ctime:'',stime:'',etime:'',status:'',tcode:'',totalCases:'',okCases:'',errCases:'',igCases:'',blCases:'',productId:'',productName:'',flowState:'',summaryRemark:'' |
|||
}, |
|||
|
|||
rawDatasBak: { |
|||
id:'',name:'',casedbId:'',casedbName:'',projectId:'',projectName:'',cuserid:'',cusername:'',ctime:'',stime:'',etime:'',status:'',tcode:'',totalCases:'',okCases:'',errCases:'',igCases:'',blCases:'',productId:'',productName:'',flowState:'',summaryRemark:'' |
|||
}, |
|||
maxTableHeight:300, |
|||
summaryRemarkEditVisible:false, |
|||
}//end return |
|||
},//end data |
|||
methods: { |
|||
|
|||
...util, |
|||
|
|||
// 取消按钮点击 父组件监听@cancel="rawDatasVisible=false" 监听 |
|||
handleCancel:function(){ |
|||
this.$refs['rawDatasRef'].resetFields(); |
|||
this.$emit('cancel'); |
|||
}, |
|||
//新增、编辑提交XmTestPlan 测试计划父组件监听@submit="afterEditSubmit" |
|||
saveSubmit: function () { |
|||
this.$refs.rawDatasRef.validate((valid) => { |
|||
if (valid) { |
|||
this.$confirm('确认提交吗?', '提示', {}).then(() => { |
|||
this.load.edit=true |
|||
let params = Object.assign({}, this.rawDatas); |
|||
var func=addXmTestPlan |
|||
if(this.currOpType=='edit'){ |
|||
func=editXmTestPlan |
|||
} |
|||
func(params).then((res) => { |
|||
this.load.edit=false |
|||
var tips=res.data.tips; |
|||
if(tips.isOk){ |
|||
this.rawDatas=res.data.data |
|||
this.initData() |
|||
this.currOpType="edit"; |
|||
this.$emit('submit');// @submit="afterAddSubmit" |
|||
} |
|||
this.$notify({ position:'bottom-left',showClose:true, message: tips.msg, type: tips.isOk?'success':'error' }); |
|||
}).catch( err =>this.load.edit=false); |
|||
}); |
|||
}else{ |
|||
this.$notify({ showClose:true, message: "表单验证不通过,请修改表单数据再提交", type: 'error' }); |
|||
} |
|||
}); |
|||
}, |
|||
initData: function(){ |
|||
if(this.xmTestPlan){ |
|||
this.rawDatas = Object.assign({},this.xmTestPlan); |
|||
} |
|||
if(this.rptDatas){ |
|||
this.rawDatas=Object.assign({},this.rptDatas) |
|||
} |
|||
this.rawDatasBak={...this.rawDatas} |
|||
}, |
|||
|
|||
editSomeFields(row,fieldName,$event){ |
|||
if(this.opType=='add'){ |
|||
return; |
|||
} |
|||
let params={}; |
|||
params['ids']=[row].map(i=>i.id) |
|||
|
|||
if(fieldName=='stime'){ |
|||
params[fieldName]=$event.stime |
|||
params.etime=$event.etime |
|||
}else if(fieldName=='cuserid'){ |
|||
params[fieldName]=$event[0].userid |
|||
params.cusername=$event[0].username |
|||
}else{ |
|||
params[fieldName]=$event |
|||
} |
|||
var func = editSomeFieldsXmTestPlan |
|||
func(params).then(res=>{ |
|||
let tips = res.data.tips; |
|||
if(tips.isOk){ |
|||
this.rawDatasBak=[...this.rawDatas] |
|||
this.$emit('edit-fields',params) |
|||
}else{ |
|||
Object.assign(this.rawDatas,this.rawDatasBak) |
|||
this.$notify({position:'bottom-left',showClose:true,message:tips.msg,type:tips.isOk?'success':'error'}) |
|||
} |
|||
}).catch((e)=>Object.assign(this.rawDatas,this.rawDatasBak)) |
|||
}, |
|||
onPorjectConfirm(row){ |
|||
this.rawDatas.projectId=row.id |
|||
this.rawDatas.projectName=row.name |
|||
this.rawDatas.name=this.rawDatas.projectName+'-测试计划-V1.0' |
|||
}, |
|||
sizeAutoChange(){ |
|||
|
|||
} |
|||
},//end method |
|||
mounted() { |
|||
this.$nextTick(() => { |
|||
initDicts(this); |
|||
this.initData() |
|||
this.maxTableHeight = util.calcTableMaxHeight(this.$refs.table.$el) |
|||
}); |
|||
} |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.box{ |
|||
|
|||
|
|||
.box-red{ |
|||
|
|||
background-color: #ff75750d; |
|||
height: 100px; |
|||
border-left-width: 2px; |
|||
border-left-color: red; |
|||
border-left-style: solid; |
|||
align-items: center; |
|||
line-height: 100px; |
|||
text-align: center; |
|||
display:flex; |
|||
flex-direction: column; |
|||
.box-info{ |
|||
display:flex; |
|||
flex-direction: column; |
|||
margin-top: 20px; |
|||
height: 100px; |
|||
line-height: 100px; |
|||
.label{ |
|||
color: #999; |
|||
height: 30px; |
|||
line-height: 30px; |
|||
font-size: 0.875rem; |
|||
} |
|||
.num{ |
|||
|
|||
height: 30px; |
|||
line-height: 30px; |
|||
color:red ; |
|||
font-size: 30px; |
|||
} |
|||
} |
|||
|
|||
} |
|||
.box-green{ |
|||
|
|||
background-color: #73d8970d;; |
|||
height: 100px; |
|||
border-left-width: 2px; |
|||
border-left-color: green; |
|||
border-left-style: solid; |
|||
|
|||
align-items: center; |
|||
line-height: 100px; |
|||
text-align: center; |
|||
display:flex; |
|||
flex-direction: column; |
|||
.box-info{ |
|||
display:flex; |
|||
flex-direction: column; |
|||
margin-top: 20px; |
|||
height: 100px; |
|||
line-height: 100px; |
|||
.label{ |
|||
color: #999; |
|||
height: 30px; |
|||
line-height: 30px; |
|||
font-size: 0.875rem; |
|||
} |
|||
.num{ |
|||
|
|||
height: 30px; |
|||
line-height: 30px; |
|||
color:green ; |
|||
font-size: 30px; |
|||
} |
|||
} |
|||
} |
|||
.box-blue{ |
|||
|
|||
background-color: #5dcfff0d; |
|||
height: 100px; |
|||
border-left-width: 2px; |
|||
border-left-color: blue; |
|||
border-left-style: solid; |
|||
|
|||
align-items: center; |
|||
line-height: 100px; |
|||
text-align: center; |
|||
display:flex; |
|||
flex-direction: column; |
|||
.box-info{ |
|||
display:flex; |
|||
flex-direction: column; |
|||
margin-top: 20px; |
|||
height: 100px; |
|||
line-height: 100px; |
|||
.label{ |
|||
color: #999; |
|||
height: 30px; |
|||
line-height: 30px; |
|||
font-size: 0.875rem; |
|||
} |
|||
.num{ |
|||
|
|||
height: 30px; |
|||
line-height: 30px; |
|||
color:blue ; |
|||
font-size: 30px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.box-orange{ |
|||
|
|||
background-color: #ffcd5d0d; |
|||
height: 100px; |
|||
border-left-width: 2px; |
|||
border-left-color: orange; |
|||
border-left-style: solid; |
|||
|
|||
align-items: center; |
|||
line-height: 100px; |
|||
text-align: center; |
|||
display:flex; |
|||
flex-direction: column; |
|||
.box-info{ |
|||
display:flex; |
|||
flex-direction: column; |
|||
margin-top: 20px; |
|||
height: 100px; |
|||
line-height: 100px; |
|||
.label{ |
|||
color: #999; |
|||
height: 30px; |
|||
line-height: 30px; |
|||
font-size: 0.875rem; |
|||
} |
|||
.num{ |
|||
|
|||
height: 30px; |
|||
line-height: 30px; |
|||
color:orange ; |
|||
font-size: 30px; |
|||
} |
|||
} |
|||
} |
|||
box-font{ |
|||
font-size: 0.875rem; |
|||
} |
|||
} |
|||
</style> |
|||