feat(报表统计): #1007217 勾选选择所有数据后翻页,勾选消失;报表优化

#1007217
勾选选择所有数据后翻页,勾选消失;报表优化:柱状图上显示数量和种类,条件搜索的下拉框显示所有下拉选项;保存和另存为时有弹出框来输入名称;动态时间保存的数据再展现时也动态更新结果
This commit is contained in:
song-tianyang 2021-10-26 15:22:34 +08:00 committed by song-tianyang
parent 712c0d69c6
commit 6bfbf5a216
9 changed files with 149 additions and 46 deletions

View File

@ -11,7 +11,7 @@ import java.util.Map;
@Setter @Setter
public class Legend { public class Legend {
private final String x = "center"; private final String x = "center";
private final String y = "bottom"; private String y = "bottom";
private final String type = "scroll"; private final String type = "scroll";
private final List<Integer> padding = Arrays.asList(0, 40, 0, 0); private final List<Integer> padding = Arrays.asList(0, 40, 0, 0);
private Map<String, Boolean> selected; private Map<String, Boolean> selected;

View File

@ -5,6 +5,7 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.List; import java.util.List;
import java.util.Map;
@Getter @Getter
@Setter @Setter
@ -18,4 +19,5 @@ public class Series {
private JSONObject encode; private JSONObject encode;
private List<String> center; private List<String> center;
private String barWidth = null; private String barWidth = null;
private Map<String,Object> label;
} }

View File

@ -28,6 +28,7 @@ public class ReportStatisticsService {
public ReportStatisticsWithBLOBs saveByRequest(ReportStatisticsSaveRequest request) { public ReportStatisticsWithBLOBs saveByRequest(ReportStatisticsSaveRequest request) {
ReportStatisticsWithBLOBs model = new ReportStatisticsWithBLOBs(); ReportStatisticsWithBLOBs model = new ReportStatisticsWithBLOBs();
model.setId(UUID.randomUUID().toString()); model.setId(UUID.randomUUID().toString());
String name = "用例分析报表"; String name = "用例分析报表";
if(StringUtils.equalsIgnoreCase(ReportStatisticsType.TEST_CASE_COUNT.name(),request.getReportType())){ if(StringUtils.equalsIgnoreCase(ReportStatisticsType.TEST_CASE_COUNT.name(),request.getReportType())){
name = "用例统计报表"; name = "用例统计报表";
@ -35,7 +36,10 @@ public class ReportStatisticsService {
}else { }else {
model.setReportType(ReportStatisticsType.TEST_CASE_ANALYSIS.name()); model.setReportType(ReportStatisticsType.TEST_CASE_ANALYSIS.name());
} }
model.setName(name); if(StringUtils.isEmpty(request.getName())){
request.setName(name);
}
model.setName(request.getName());
model.setDataOption(request.getDataOption()); model.setDataOption(request.getDataOption());
model.setSelectOption(request.getSelectOption()); model.setSelectOption(request.getSelectOption());
model.setCreateTime(System.currentTimeMillis()); model.setCreateTime(System.currentTimeMillis());

View File

@ -547,7 +547,7 @@ public class TestCaseCountService {
List<User> userList = userService.getUserList(); List<User> userList = userService.getUserList();
Map<String, String> userIdMap = new HashMap<>(); Map<String, String> userIdMap = new HashMap<>();
for (User model : userList) { for (User model : userList) {
userIdMap.put(model.getId(), model.getId() + "\n(" + model.getName() + ")"); userIdMap.put(model.getId(), model.getName() + "\n(" + model.getId() + ")");
} }
return userIdMap; return userIdMap;
} }
@ -608,6 +608,11 @@ public class TestCaseCountService {
Map<String, String> caseDescMap = this.getCaseDescMap(); Map<String, String> caseDescMap = this.getCaseDescMap();
//柱状图上显示数字
Map<String,Object> labelMap = new HashMap<>();
labelMap.put("show",true);
labelMap.put("position","inside");
Series tetcaseSeries = new Series(); Series tetcaseSeries = new Series();
tetcaseSeries.setName(caseDescMap.get("testCaseDesc")); tetcaseSeries.setName(caseDescMap.get("testCaseDesc"));
tetcaseSeries.setColor("#F38F1F"); tetcaseSeries.setColor("#F38F1F");
@ -616,6 +621,7 @@ public class TestCaseCountService {
tetcaseSeries.setStack("total"); tetcaseSeries.setStack("total");
tetcaseSeries.setData(testCaseCountList); tetcaseSeries.setData(testCaseCountList);
tetcaseSeries.setBarWidth("50"); tetcaseSeries.setBarWidth("50");
tetcaseSeries.setLabel(labelMap);
seriesList.add(tetcaseSeries); seriesList.add(tetcaseSeries);
Series apiSeries = new Series(); Series apiSeries = new Series();
@ -624,6 +630,7 @@ public class TestCaseCountService {
apiSeries.setType("bar"); apiSeries.setType("bar");
apiSeries.setStack("total"); apiSeries.setStack("total");
apiSeries.setData(apiCaseCountList); apiSeries.setData(apiCaseCountList);
apiSeries.setLabel(labelMap);
seriesList.add(apiSeries); seriesList.add(apiSeries);
Series scenarioSeries = new Series(); Series scenarioSeries = new Series();
@ -632,6 +639,7 @@ public class TestCaseCountService {
scenarioSeries.setType("bar"); scenarioSeries.setType("bar");
scenarioSeries.setStack("total"); scenarioSeries.setStack("total");
scenarioSeries.setData(scenarioCaseCountList); scenarioSeries.setData(scenarioCaseCountList);
scenarioSeries.setLabel(labelMap);
seriesList.add(scenarioSeries); seriesList.add(scenarioSeries);
Series loadSeries = new Series(); Series loadSeries = new Series();
@ -640,11 +648,16 @@ public class TestCaseCountService {
loadSeries.setType("bar"); loadSeries.setType("bar");
loadSeries.setStack("total"); loadSeries.setStack("total");
loadSeries.setData(loadCaseCountList); loadSeries.setData(loadCaseCountList);
loadSeries.setLabel(labelMap);
seriesList.add(loadSeries); seriesList.add(loadSeries);
dto.setXAxis(xAxis); dto.setXAxis(xAxis);
dto.setYAxis(new YAxis()); dto.setYAxis(new YAxis());
dto.setSeries(seriesList); dto.setSeries(seriesList);
Legend legend = new Legend();
legend.setY("top");
dto.setLegend(legend);
} }
private void formatLegend(Legend legend, List<String> datas, TestCaseCountRequest yrequest) { private void formatLegend(Legend legend, List<String> datas, TestCaseCountRequest yrequest) {
@ -682,7 +695,7 @@ public class TestCaseCountService {
for (User user : userList) { for (User user : userList) {
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
map.put("id", user.getId()); map.put("id", user.getId());
map.put("label", user.getId() + "(" + user.getName() + ")"); map.put("label", user.getName() + "(" + user.getId() + ")");
returnUserList.add(map); returnUserList.add(map);
} }

View File

@ -407,8 +407,10 @@ export default {
clearSelectRows() { clearSelectRows() {
this.selectRows.clear(); this.selectRows.clear();
this.selectIds = []; this.selectIds = [];
if(!this.condition.selectAll){
this.condition.selectAll = false; this.condition.selectAll = false;
this.condition.unSelectIds = []; this.condition.unSelectIds = [];
}
this.selectDataCounts = 0; this.selectDataCounts = 0;
if (this.$refs.table) { if (this.$refs.table) {
this.$refs.table.clearSelection(); this.$refs.table.clearSelection();

View File

@ -18,7 +18,7 @@
<ms-drawer :visible="testCaseTrendDrawer" :size="100" @close="close" direction="right" :show-full-screen="false" :is-show-close="false" style="overflow: hidden"> <ms-drawer :visible="testCaseTrendDrawer" :size="100" @close="close" direction="right" :show-full-screen="false" :is-show-close="false" style="overflow: hidden">
<template v-slot:header> <template v-slot:header>
<report-header :title="$t('commons.report_statistics.test_case_analysis')" :history-report-id="historyReportId" <report-header :title="$t('commons.report_statistics.test_case_analysis')" :history-report-id="historyReportId"
@closePage="close" @saveReport="saveReport" @selectAndSaveReport="selectAndSaveReport"/> @closePage="close" @saveReport="openSaveReportDialog('save')" @selectAndSaveReport="openSaveReportDialog('saveAs')"/>
</template> </template>
<test-analysis-container @initHistoryReportId="initHistoryReportId" ref="testAnalysisContainer"/> <test-analysis-container @initHistoryReportId="initHistoryReportId" ref="testAnalysisContainer"/>
</ms-drawer> </ms-drawer>
@ -27,10 +27,26 @@
<ms-drawer :visible="testCaseCountDrawer" :size="100" @close="close" direction="right" :show-full-screen="false" :is-show-close="false" style="overflow: hidden"> <ms-drawer :visible="testCaseCountDrawer" :size="100" @close="close" direction="right" :show-full-screen="false" :is-show-close="false" style="overflow: hidden">
<template v-slot:header> <template v-slot:header>
<report-header :title="$t('commons.report_statistics.test_case_count')" :history-report-id="historyReportId" <report-header :title="$t('commons.report_statistics.test_case_count')" :history-report-id="historyReportId"
@closePage="close" @saveReport="saveReport" @selectAndSaveReport="selectAndSaveReport"/> @closePage="close" @saveReport="openSaveReportDialog('save')" @selectAndSaveReport="openSaveReportDialog('saveAs')"/>
</template> </template>
<test-case-count-container @initHistoryReportId="initHistoryReportId" ref="testCaseCountContainer"/> <test-case-count-container @initHistoryReportId="initHistoryReportId" ref="testCaseCountContainer"/>
</ms-drawer> </ms-drawer>
<el-dialog
:title="$t('commons.save')"
:visible.sync="dialogFormVisible"
width="30%"
:before-close="handleCloseSaveReportDialog">
<el-form :model="form" :rules="saveReportRules" ref="saveReportRuleForm">
<el-form-item :label="$t('commons.input_name')" prop="reportName" label-width="120px">
<el-input v-model="form.reportName" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="saveReport">{{$t('commons.confirm')}}</el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
@ -51,6 +67,17 @@
testCaseCountDrawer: false, testCaseCountDrawer: false,
historyReportId:"", historyReportId:"",
reportTypes: [{id: 'track', name: this.$t('test_track.test_track')}], reportTypes: [{id: 'track', name: this.$t('test_track.test_track')}],
dialogFormVisible: false,
form: {
reportName: "",
saveType: "",
},
saveReportRules: {
reportName: [
{ required: true, message: this.$t('commons.input_name'), trigger: 'blur' },
{ min: 1, max: 20, message: '长度不大于20个字符', trigger: 'blur' }
],
}
} }
}, },
methods: { methods: {
@ -65,23 +92,34 @@
this.testCaseTrendDrawer = false; this.testCaseTrendDrawer = false;
this.testCaseCountDrawer = false; this.testCaseCountDrawer = false;
}, },
saveReport(){ openSaveReportDialog(saveType){
if(this.testCaseTrendDrawer){ this.form.saveType = saveType;
this.$refs.testAnalysisContainer.saveReport(); this.dialogFormVisible = true;
}else if(this.testCaseCountDrawer){
this.$refs.testCaseCountContainer.saveReport();
}
}, },
selectAndSaveReport(){ saveReport(){
this.$refs['saveReportRuleForm'].validate((valid) => {
if (valid) {
if(this.testCaseTrendDrawer){ if(this.testCaseTrendDrawer){
this.$refs.testAnalysisContainer.selectAndSaveReport(); this.$refs.testAnalysisContainer.saveAndSaveAsReport(this.form.reportName,this.form.saveType);
}else if(this.testCaseCountDrawer){ }else if(this.testCaseCountDrawer){
this.$refs.testCaseCountContainer.selectAndSaveReport(); this.$refs.testCaseCountContainer.saveAndSaveAsReport(this.form.reportName,this.form.saveType);
} }
this.form.reportName = "";
this.form.saveType = "";
this.dialogFormVisible = false;
} else {
return false;
}
});
}, },
initHistoryReportId(reportId){ initHistoryReportId(reportId){
this.historyReportId = reportId; this.historyReportId = reportId;
}, },
handleCloseSaveReportDialog(){
this.form.reportName = "";
this.form.saveType = "";
this.dialogFormVisible = false;
}
}, },
} }
</script> </script>

View File

@ -1,9 +1,8 @@
<template> <template>
<div> <div>
<el-container v-loading="loading" id="reportAnalysis" style="overflow: scroll"> <el-container v-loading="loading" id="reportAnalysis" :style="{ 'max-height': (h-50) + 'px', 'overflow': 'auto'}" >
<el-container class="ms-row"> <el-aside v-if="!isHide" :width="!isHide ?'235px':'0px'" :style="{ 'margin-left': '5px'}" >
<el-aside v-if="!isHide" :width="!isHide ?'235px':'0px'" :style="{ 'max-height': h-50 + 'px', 'margin-left': '5px'}" >
<history-report-data report-type="TEST_CASE_COUNT" <history-report-data report-type="TEST_CASE_COUNT"
@selectReport="selectReport" @removeHistoryReportId="removeHistoryReportId" @selectReport="selectReport" @removeHistoryReportId="removeHistoryReportId"
ref="historyReport"/> ref="historyReport"/>
@ -21,7 +20,6 @@
<test-case-count-filter @filterCharts="filterCharts" ref="countFilter"/> <test-case-count-filter @filterCharts="filterCharts" ref="countFilter"/>
</el-aside> </el-aside>
</el-container> </el-container>
</el-container>
</div> </div>
</template> </template>
@ -137,8 +135,9 @@ export default {
this.options.order = order; this.options.order = order;
this.filterCharts(this.options); this.filterCharts(this.options);
}, },
saveReport() { saveReport(reportName) {
let obj = {}; let obj = {};
obj.name = reportName;
obj.projectId = getCurrentProjectID(); obj.projectId = getCurrentProjectID();
obj.selectOption = JSON.stringify(this.options); obj.selectOption = JSON.stringify(this.options);
let dataOptionObj = { let dataOptionObj = {
@ -197,10 +196,17 @@ export default {
return ""; return "";
} }
}, },
selectAndSaveReport(){ selectAndSaveReport(reportName){
let opt = this.$refs.countFilter.getOption(); let opt = this.$refs.countFilter.getOption();
this.options = opt; this.options = opt;
this.saveReport(); this.saveReport(reportName);
},
saveAndSaveAsReport(reportName,saveType){
if(saveType === 'save'){
this.saveReport(reportName);
}else if(saveType === 'saveAs'){
this.selectAndSaveReport(reportName);
}
} }
}, },
}; };

View File

@ -1,6 +1,7 @@
<template> <template>
<div v-loading="loading"> <div v-loading="loading">
<el-card :style="{height: h + 'px'}" class="ms-card"> <!-- <el-card :style="{height: h + 'px'}" class="ms-card">-->
<el-card class="ms-card">
<el-row style="padding-top: 10px"> <el-row style="padding-top: 10px">
<p class="tip"><span style="margin-left: 5px"></span> {{ $t('commons.report_statistics.options') }}</p> <p class="tip"><span style="margin-left: 5px"></span> {{ $t('commons.report_statistics.options') }}</p>
</el-row> </el-row>
@ -54,26 +55,26 @@
<el-container> <el-container>
<el-aside width="73px" style="overflow: hidden"> <el-aside width="73px" style="overflow: hidden">
<div v-if="option.filters.length > 1" style="height: 100%" id="moreOptionTypeDiv"> <div v-if="option.filters.length > 1" style="height: 100%" id="moreOptionTypeDiv">
<div class="top-line-box" :style="{ height:lineDivHeight+'px'}"> <div class="top-line-box" :style="{ height:lineDivTopHeight+'px',marginTop:lineDivMarginTopHeight+'px'}">
</div> </div>
<div> <div>
<el-select class="ms-http-select" size="small" v-model="option.filterType" style="width: 70px"> <el-select class="ms-http-select" size="small" v-model="option.filterType" style="width: 70px">
<el-option v-for="item in filterTypes" :key="item.id" :label="item.label" :value="item.id"/> <el-option v-for="item in filterTypes" :key="item.id" :label="item.label" :value="item.id"/>
</el-select> </el-select>
</div> </div>
<div class="bottom-line-box" :style="{ height:lineDivHeight+'px'}"> <div class="bottom-line-box" :style="{ height:lineDivBottomHeight+'px'}">
</div> </div>
</div> </div>
</el-aside> </el-aside>
<el-main v-if="optionLoad" style="padding: 0px"> <el-main v-if="optionLoad" style="padding: 0px">
<el-row v-for="filterItem in option.filters" :key="filterItem.id" style="margin-bottom: 5px"> <el-row v-for="filterItem in option.filters" :key="filterItem.id" style="margin-bottom: 5px">
<el-col :span="24"> <el-col :span="24" name="itemOptions">
<el-select style="width: 100px" class="ms-http-select" size="small" v-model="filterItem.type"> <el-select style="width: 100px" class="ms-http-select" size="small" v-model="filterItem.type">
<el-option v-for="item in getFilterOptionKey(filterItem.type)" :key="item.type" :label="item.name" :value="item.type"/> <el-option v-for="item in getFilterOptionKey(filterItem.type)" :key="item.type" :label="item.name" :value="item.type"/>
</el-select> </el-select>
<span style="margin-left:10px;margin-right:10px">{{ $t('commons.report_statistics.report_filter.belone') }}</span> <span style="margin-left:10px;margin-right:10px">{{ $t('commons.report_statistics.report_filter.belone') }}</span>
<el-select style="width:173px" :collapse-tags="true" class="ms-http-select" size="small" multiple filterable v-model="filterItem.values" v-if="getFilterOptions(filterItem.type).length > 0"> <el-select style="width:173px" class="ms-http-select" size="small" multiple filterable v-model="filterItem.values" v-if="getFilterOptions(filterItem.type).length > 0">
<el-option v-for="itemOption in getFilterOptions(filterItem.type)" :key="itemOption.id" :label="itemOption.label" :value="itemOption.id"/> <el-option v-for="itemOption in getFilterOptions(filterItem.type)" :key="itemOption.id" :label="itemOption.label" :value="itemOption.id"/>
</el-select> </el-select>
<el-input style="width:173px" v-model="filterItem.value" size="small" v-else ></el-input> <el-input style="width:173px" v-model="filterItem.value" size="small" v-else ></el-input>
@ -146,7 +147,9 @@ export default {
], ],
}, },
h: document.documentElement.clientHeight + 80, h: document.documentElement.clientHeight + 80,
lineDivHeight: 0, lineDivTopHeight: 0,
lineDivMarginTopHeight: 0,
lineDivBottomHeight: 0,
disabled: false, disabled: false,
loading: false, loading: false,
optionLoad: true, optionLoad: true,
@ -237,13 +240,37 @@ export default {
handler: function () { handler: function () {
this.$nextTick(() => { this.$nextTick(() => {
this.lineDivHeight = 0; this.lineDivHeight = 0;
// let elem = document.getElementById("moreOptionTypeDiv"); setTimeout(() => {
if(this.option.filters.length > 1){ let itemOptions = document.getElementsByName("itemOptions");
let countPageHeight = (this.option.filters.length)* 32 + (this.option.filters.length-1)*5; // let optionTypeDiv = document.getElementById("moreOptionTypeDiv");
if(countPageHeight > 32){ // if(optionTypeDiv){
this.lineDivHeight = (countPageHeight-32)/2-11; if(itemOptions && itemOptions.length > 1){
let optionTypeHeight = 0;
for(let i = 0; i < itemOptions.length; i ++){
let itemHeight = itemOptions[i].offsetHeight;
if(optionTypeHeight != 0){
optionTypeHeight += 5;
} }
optionTypeHeight+= itemHeight;
} }
let firstHeight = itemOptions[0].offsetHeight;
let endHeight = itemOptions[itemOptions.length-1].offsetHeight;
this.lineDivMarginTopHeight = ((firstHeight-32)/2+16);
this.lineDivTopHeight = ((optionTypeHeight/2 - this.lineDivMarginTopHeight-16));
let divMarginBottom = ((endHeight-32)/2+16);
this.lineDivBottomHeight = ((optionTypeHeight - 32 - this.lineDivTopHeight - this.lineDivMarginTopHeight - divMarginBottom ));
}
// }
}, 100);
// moreOptionTypeDiv
// if(this.option.filters.length > 1){
// let countPageHeight = (this.option.filters.length)* 32 + (this.option.filters.length-1)*5;
// if(countPageHeight > 32){
// this.lineDivHeight = (countPageHeight-32)/2-11;
// }
// }
}); });
}, },
deep: true deep: true
@ -254,6 +281,9 @@ export default {
this.loading = true; this.loading = true;
this.option = opt; this.option = opt;
this.$nextTick(() => { this.$nextTick(() => {
if(this.option.timeType === "dynamicTime"){
this.init();
}
this.loading = false; this.loading = false;
}); });
}, },
@ -374,13 +404,13 @@ export default {
.ms-card { .ms-card {
width: 480px; width: 480px;
overflow: auto;
} }
.top-line-box{ .top-line-box{
border-top: 1px solid; border-top: 1px solid;
border-left: 1px solid; border-left: 1px solid;
margin-left: 32px; margin-left: 32px;
margin-top: 10px;
border-top-left-radius: 10px; border-top-left-radius: 10px;
} }
@ -393,9 +423,9 @@ export default {
/deep/ .el-select__tags-text { /deep/ .el-select__tags-text {
display: inline-block; display: inline-block;
max-width: 50px; max-width: 117px;
overflow: hidden; overflow: hidden;
text-overflow:ellipsis; text-overflow:ellipsis;
white-space: nowrap; /*white-space: nowrap;*/
} }
</style> </style>

View File

@ -86,8 +86,9 @@
this.options.order = order; this.options.order = order;
this.filterCharts(this.options); this.filterCharts(this.options);
}, },
saveReport() { saveReport(reportName) {
let obj = {}; let obj = {};
obj.name = reportName;
obj.projectId = getCurrentProjectID(); obj.projectId = getCurrentProjectID();
obj.selectOption = JSON.stringify(this.options); obj.selectOption = JSON.stringify(this.options);
let dataOptionObj = { let dataOptionObj = {
@ -148,10 +149,17 @@
removeHistoryReportId(){ removeHistoryReportId(){
this.$emit('initHistoryReportId',""); this.$emit('initHistoryReportId',"");
}, },
selectAndSaveReport(){ selectAndSaveReport(reportName){
let opt = this.$refs.analysisFilter.getOption(); let opt = this.$refs.analysisFilter.getOption();
this.options = opt; this.options = opt;
this.saveReport(); this.saveReport(reportName);
},
saveAndSaveAsReport(reportName,saveType){
if(saveType === 'save'){
this.saveReport(reportName);
}else if(saveType === 'saveAs'){
this.selectAndSaveReport(reportName);
}
} }
}, },
} }