fix(报表统计): 修复已保存过的报表点击会报错的缺陷

修复已保存过的报表点击会报错的缺陷
This commit is contained in:
song-tianyang 2021-11-22 20:08:49 +08:00 committed by song-tianyang
parent 9a43f5eda0
commit 096fc3e935
3 changed files with 251 additions and 295 deletions

View File

@ -78,6 +78,9 @@ public class ReportStatisticsService {
return blob;
}
private TestCaseCountTableDataDTO countShowTable(String groupName, List<String> yaxis, List<TestCaseCountTableDTO> dtos) {
if(yaxis == null){
yaxis = new ArrayList<>();
}
TestCaseCountTableDataDTO returnDTO = new TestCaseCountTableDataDTO();
String [] headers = new String[]{groupName,"总计","testCase","apiCase","scenarioCase","loadCaseCount"};
@ -86,6 +89,7 @@ public class ReportStatisticsService {
boolean showApi = true;
boolean showScenario = true;
boolean showLoad = true;
for (String head : headers) {
if(StringUtils.equalsAnyIgnoreCase(head,groupName,"总计") || yaxis.contains(head)){
TestCaseCountTableItemDataDTO headData = new TestCaseCountTableItemDataDTO();

View File

@ -1,33 +1,36 @@
<template>
<div>
<el-container v-loading="loading" id="reportAnalysis" :style="{ 'max-height': (h-50) + 'px', 'overflow': 'auto'}" >
<el-aside v-if="!isHide" :width="!isHide ?'235px':'0px'" :style="{ 'margin-left': '5px'}" >
<history-report-data report-type="TEST_CASE_COUNT"
@selectReport="selectReport" @removeHistoryReportId="removeHistoryReportId"
ref="historyReport"/>
</el-aside>
<el-main class="ms-main" style="padding: 0px 5px 0px">
<div>
<test-case-count-chart @hidePage="hidePage" @orderCharts="orderCharts" ref="analysisChart"
:chart-width="chartWidth" :load-option="loadOption" :pie-option="pieOption"/>
</div>
<div class="ms-row" v-if="!isHide">
<test-case-count-table :group-name="getGroupNameStr(options.xaxis)" :show-coloums="options.yaxis" :tableData="tableData"/>
</div>
</el-main>
<el-aside v-if="!isHide" style="height: 100%" :width="!isHide ?'485px':'0px'">
<test-case-count-filter @filterCharts="filterCharts" ref="countFilter"/>
</el-aside>
<el-container v-loading="loading" id="reportAnalysis" :style="{ 'max-height': (h-50) + 'px', 'overflow': 'auto'}">
<el-aside v-if="!isHide" :width="!isHide ?'235px':'0px'" :style="{ 'margin-left': '5px'}">
<history-report-data report-type="TEST_CASE_COUNT"
@selectReport="selectReport" @removeHistoryReportId="removeHistoryReportId"
ref="historyReport"/>
</el-aside>
<el-main class="ms-main" style="padding: 0px 5px 0px">
<div>
<test-case-count-chart @hidePage="hidePage" @orderCharts="orderCharts"
ref="analysisChart" @updateChartType="updateChartType"
:chart-width="chartWidth" :load-option="loadOption" :pie-option="pieOption"/>
</div>
<div class="ms-row" v-if="!isHide">
<test-case-count-table :group-name="getGroupNameStr(options.xaxis)" :show-coloums="options.yaxis"
:tableData="tableData"/>
</div>
</el-main>
<el-aside v-if="!isHide" style="height: 100%" :width="!isHide ?'485px':'0px'">
<test-case-count-filter @filterCharts="filterCharts" ref="countFilter"/>
</el-aside>
</el-container>
</div>
</template>
<script>
import TestCaseCountChart from "./chart/TestCaseCountChart";
import TestCaseCountTable from "@/business/components/reportstatistics/projectstatistics/casecount/table/TestCaseCountTable";
import TestCaseCountTable
from "@/business/components/reportstatistics/projectstatistics/casecount/table/TestCaseCountTable";
import TestCaseCountFilter from "./filter/TestCaseCountFilter";
import {exportPdf,getCurrentProjectID} from "@/common/js/utils";
import {exportPdf, getCurrentProjectID} from "@/common/js/utils";
import html2canvas from 'html2canvas';
import HistoryReportData from "../../base/HistoryReportData";
@ -41,6 +44,7 @@ export default {
options: {},
chartWidth: 0,
tableHeight: 300,
chartType: "bar",
loadOption: {
legend: {},
xAxis: {},
@ -62,6 +66,9 @@ export default {
};
},
methods: {
updateChartType(value) {
this.chartType = value;
},
handleExport() {
let name = this.$t('commons.report_statistics.test_case_analysis');
this.$nextTick(function () {
@ -87,13 +94,12 @@ export default {
let data = response.data.barChartDTO;
let pieData = response.data.pieChartDTO;
let selectTableData = response.data.tableDTOs;
this.initPic(data,pieData,selectTableData);
},error => {
this.initPic(data, pieData, selectTableData);
}, error => {
this.loading = false;
});
},
initPic(barData,pieData,selectTableData){
initPic(barData, pieData, selectTableData) {
this.loading = true;
if (barData) {
this.loadOption.legend = barData.legend;
@ -126,7 +132,7 @@ export default {
this.tableData = selectTableData;
}
this.loading = false;
this.$refs.analysisChart.reload();
this.$refs.analysisChart.generateOption(this.chartType);
},
filterCharts(opt) {
this.init(opt);
@ -144,6 +150,7 @@ export default {
loadOption: this.loadOption,
pieOption: this.pieOption,
tableData: this.tableData,
chartType: this.chartType,
};
obj.dataOption = JSON.stringify(dataOptionObj);
obj.reportType = 'TEST_CASE_COUNT';
@ -152,59 +159,63 @@ export default {
this.$refs.historyReport.initReportData();
});
},
selectReport(selectId){
if(selectId){
selectReport(selectId) {
if (selectId) {
this.loading = true;
let paramObj = {
id:selectId
id: selectId
}
this.$post('/history/report/selectById',paramObj, response => {
this.$post('/history/report/selectById', paramObj, response => {
let reportData = response.data;
if(reportData){
if(reportData.dataOption){
if (reportData) {
if (reportData.dataOption) {
let dataOptionObj = JSON.parse(reportData.dataOption);
this.initPic(dataOptionObj.loadOption,dataOptionObj.pieOption,dataOptionObj.tableData);
if (dataOptionObj.chartType) {
this.chartType = dataOptionObj.chartType;
}else {
this.chartType = "bar";
}
this.initPic(dataOptionObj.loadOption, dataOptionObj.pieOption, dataOptionObj.tableData);
}
if(reportData.selectOption){
if (reportData.selectOption) {
let selectOptionObj = JSON.parse(reportData.selectOption);
this.$refs.countFilter.initSelectOption(selectOptionObj);
}
this.loading = false;
}
}, (error) => {
this.loading = false;
});
this.$emit('initHistoryReportId',selectId);
this.$emit('initHistoryReportId', selectId);
}
},
removeHistoryReportId(){
this.$emit('initHistoryReportId',"");
removeHistoryReportId() {
this.$emit('initHistoryReportId', "");
},
getGroupNameStr(groupName){
if(groupName === 'creator') {
getGroupNameStr(groupName) {
if (groupName === 'creator') {
return this.$t('commons.report_statistics.report_filter.select_options.creator');
}else if(groupName === 'maintainer'){
} else if (groupName === 'maintainer') {
return this.$t('commons.report_statistics.report_filter.select_options.maintainer');
}else if(groupName === 'casetype'){
} else if (groupName === 'casetype') {
return this.$t('commons.report_statistics.report_filter.select_options.case_type');
}else if(groupName === 'casestatus'){
} else if (groupName === 'casestatus') {
return this.$t('commons.report_statistics.report_filter.select_options.case_status');
}else if(groupName === 'caselevel'){
} else if (groupName === 'caselevel') {
return this.$t('commons.report_statistics.report_filter.select_options.case_level');
}else {
} else {
return "";
}
},
selectAndSaveReport(reportName){
selectAndSaveReport(reportName) {
let opt = this.$refs.countFilter.getOption();
this.options = opt;
this.saveReport(reportName);
},
saveAndSaveAsReport(reportName,saveType){
if(saveType === 'save'){
saveAndSaveAsReport(reportName, saveType) {
if (saveType === 'save') {
this.saveReport(reportName);
}else if(saveType === 'saveAs'){
} else if (saveType === 'saveAs') {
this.selectAndSaveReport(reportName);
}
}

View File

@ -2,7 +2,7 @@
<div v-loading="loading">
<el-card class="ms-test-chart" :style="{ width: w+'px', height: h + 'px'}" ref="msDrawer">
<el-row class="ms-row">
<p class="tip"><span style="margin-left: 5px"></span> {{$t('commons.report_statistics.chart')}} </p>
<p class="tip"><span style="margin-left: 5px"></span> {{ $t('commons.report_statistics.chart') }} </p>
<div class="ms-test-chart-header" v-if="!readOnly">
<el-dropdown @command="exportCommand" :hide-on-click="false">
<span class="el-dropdown-link">
@ -22,285 +22,226 @@
<el-option :key="t.id" :value="t.id" :label="t.name" v-for="t in orders"/>
</el-select>
<span style="margin: 0px 10px 10px">|</span>
<font-awesome-icon v-if="!isFullScreen && showFullScreen" class="report-alt-ico" :icon="['fa', 'expand-alt']" size="lg" @click="fullScreen"/>
<font-awesome-icon v-if="isFullScreen && showFullScreen" class="report-alt-ico" :icon="['fa', 'compress-alt']" size="lg" @click="unFullScreen"/>
<font-awesome-icon v-if="!isFullScreen && showFullScreen" class="report-alt-ico" :icon="['fa', 'expand-alt']"
size="lg" @click="fullScreen"/>
<font-awesome-icon v-if="isFullScreen && showFullScreen" class="report-alt-ico" :icon="['fa', 'compress-alt']"
size="lg" @click="unFullScreen"/>
</div>
</el-row>
<el-row style="overflow: auto">
<ms-chart ref="chart1" v-if="!loading" :options="dataOption" :style="{width: chartWidthNumber+'px', height: (h-50) + 'px'}" class="chart-config" :autoresize="true" id="picChart"/>
<ms-chart ref="chart1" v-if="!loading" :options="dataOption"
:style="{width: chartWidthNumber+'px', height: (h-50) + 'px'}" class="chart-config" :autoresize="true"
id="picChart"/>
</el-row>
</el-card>
</div>
</template>
<script>
import echarts from "echarts";
import MsChart from "@/business/components/common/chart/MsChart";
import echarts from "echarts";
import MsChart from "@/business/components/common/chart/MsChart";
export default {
name: "TestCaseCountChart",
components: {MsChart},
props: {
loadOption: {},
pieOption: {},
chartWidth:Number,
needFullScreen: Boolean,
readOnly:Boolean,
export default {
name: "TestCaseCountChart",
components: {MsChart},
props: {
loadOption: {},
pieOption: {},
chartWidth: Number,
needFullScreen: Boolean,
readOnly: Boolean,
},
data() {
return {
dataOption: {},
x: 0,
y: 0,
w: document.documentElement.clientWidth - 760,
h: document.documentElement.clientHeight * 0.5,
chartWidthNumber: document.documentElement.clientWidth - 760,
isFullScreen: false,
originalW: 100,
originalH: 100,
showFullScreen: {
type: Boolean,
default() {
return true;
}
},
charts: [
{id: 'bar', name: this.$t('commons.report_statistics.bar')},
{id: 'pie', name: this.$t('commons.report_statistics.pie')}
],
order: "",
orders: [{id: '', name: '默认排序'}, {id: 'desc', name: this.$t('commons.report_statistics.desc')}, {
id: 'asc',
name: this.$t('commons.report_statistics.asc')
}],
loading: false,
options: {},
chartType: "bar",
}
},
created() {
this.selectedPicType = this.chartType;
this.dataOption = this.loadOption;
if (this.needFullScreen) {
this.w = document.documentElement.clientWidth;
}
this.reload();
},
watch: {
chartWidth() {
this.countChartWidth();
},
data() {
return {
dataOption:{},
x: 0,
y: 0,
w: document.documentElement.clientWidth - 760,
h: document.documentElement.clientHeight * 0.5 ,
chartWidthNumber:document.documentElement.clientWidth - 760,
isFullScreen: false,
originalW: 100,
originalH: 100,
showFullScreen: {
type: Boolean,
default() {
return true;
}
},
//
chartType: "bar",
charts: [
{id: 'bar', name: this.$t('commons.report_statistics.bar')},
{id: 'pie', name: this.$t('commons.report_statistics.pie')}
],
order: "",
orders: [{id: '', name: '默认排序'},{id: 'desc', name: this.$t('commons.report_statistics.desc')}, {id: 'asc', name: this.$t('commons.report_statistics.asc')}],
loading: false,
options: {},
pieItemOption:{
dataset: [{
source: [
['Product', 'Sales', 'Price', 'Year'],
['Cake', 123, 32, 2011],
['Cereal', 231, 14, 2011],
['Tofu', 235, 5, 2011],
['Dumpling', 341, 25, 2011],
['Biscuit', 122, 29, 2011],
['Cake', 143, 30, 2012],
['Cereal', 201, 19, 2012],
['Tofu', 255, 7, 2012],
['Dumpling', 241, 27, 2012],
['Biscuit', 102, 34, 2012],
['Cake', 153, 28, 2013],
['Cereal', 181, 21, 2013],
['Tofu', 395, 4, 2013],
['Dumpling', 281, 31, 2013],
['Biscuit', 92, 39, 2013],
['Cake', 223, 29, 2014],
['Cereal', 211, 17, 2014],
['Tofu', 345, 3, 2014],
['Dumpling', 211, 35, 2014],
['Biscuit', 72, 24, 2014],
],
}, {
transform: {
type: 'filter',
config: { dimension: 'Year', value: 2011 }
},
}, {
transform: {
type: 'filter',
config: { dimension: 'Year', value: 2012 }
}
}, {
transform: {
type: 'filter',
config: { dimension: 'Year', value: 2013 }
}
}],
series: [{
type: 'pie', radius: 50, center: ['50%', '25%'],
datasetIndex: 1
}, {
type: 'pie', radius: 50, center: ['50%', '50%'],
datasetIndex: 2
}, {
type: 'pie', radius: 50, center: ['50%', '75%'],
datasetIndex: 3
}],
media: [{
query: { minAspectRatio: 1 },
option: {
series: [
{ center: ['25%', '50%'] },
{ center: ['50%', '50%'] },
{ center: ['75%', '50%'] }
]
}
}, {
option: {
series: [
{ center: ['50%', '25%'] },
{ center: ['50%', '50%'] },
{ center: ['50%', '75%'] }
]
}
}]
},
chartType() {
this.$emit("updateChartType",this.chartType);
this.countChartWidth();
},
},
methods: {
countChartWidth() {
if (this.chartWidth === 0 || this.chartType === 'bar') {
this.chartWidthNumber = this.w;
} else {
this.chartWidthNumber = this.chartWidth;
}
},
created() {
this.dataOption = this.loadOption;
if(this.needFullScreen){
this.w = document.documentElement.clientWidth;
orderCharts() {
this.$emit('orderCharts', this.order);
},
generateOption(chartTypeParam) {
if(chartTypeParam){
this.chartType = chartTypeParam;
}
if (this.chartType === 'pie') {
this.dataOption = this.pieOption;
} else {
this.dataOption = this.loadOption;
}
this.dataOption.series.forEach(item => {
item.type = this.chartType;
});
this.reload();
},
watch:{
chartWidth(){
this.countChartWidth();
},
chartType(){
this.countChartWidth();
},
reload() {
this.loading = true
this.$nextTick(() => {
this.loading = false;
})
},
methods: {
countChartWidth(){
if(this.chartWidth === 0 || this.chartType === 'bar'){
this.chartWidthNumber = this.w;
}else {
this.chartWidthNumber = this.chartWidth;
fullScreen() {
this.originalW = this.w;
this.originalH = this.h;
this.w = document.body.clientWidth - 50;
this.h = document.body.clientHeight;
this.isFullScreen = true;
this.$emit('hidePage', true);
},
unFullScreen() {
this.w = this.originalW;
this.h = this.originalH;
this.isFullScreen = false;
this.$emit('hidePage', false);
},
getImages(command) {
let imageType = 'image/png';
if (command === 'jpg') {
imageType = 'image/jpg';
}
let returnImageDatas = "";
if (document.getElementById('picChart')) {
let chartsCanvas = document.getElementById('picChart').querySelectorAll('canvas')[0];
if (chartsCanvas) {
// toDataURL()canvascanvasbase64
returnImageDatas = chartsCanvas && chartsCanvas.toDataURL(imageType);
}
},
orderCharts() {
this.$emit('orderCharts', this.order);
},
generateOption() {
if(this.chartType === 'pie'){
this.dataOption = this.pieOption;
}else {
this.dataOption = this.loadOption;
}
this.$emit("getImage", returnImageDatas);
return returnImageDatas;
},
exportCommand(command) {
let fileName = 'report_pic.' + command;
if (document.getElementById('picChart')) {
let chartsCanvas = document.getElementById('picChart').querySelectorAll('canvas')[0]
let mime = 'image/png';
if (command === 'jpg') {
mime = 'image/jpg';
}
this.dataOption.series.forEach(item => {
item.type = this.chartType;
});
this.reload();
},
reload() {
this.loading = true
this.$nextTick(() => {
this.loading = false;
})
},
fullScreen() {
this.originalW = this.w;
this.originalH = this.h;
this.w = document.body.clientWidth - 50;
this.h = document.body.clientHeight;
this.isFullScreen = true;
this.$emit('hidePage', true);
},
unFullScreen() {
this.w = this.originalW;
this.h = this.originalH;
this.isFullScreen = false;
this.$emit('hidePage', false);
},
getImages(command){
let imageType = 'image/png';
if(command === 'jpg'){
imageType = 'image/jpg';
}
let returnImageDatas = "";
if (document.getElementById('picChart')) {
let chartsCanvas = document.getElementById('picChart').querySelectorAll('canvas')[0];
if (chartsCanvas) {
// toDataURL()canvascanvasbase64
returnImageDatas = chartsCanvas && chartsCanvas.toDataURL(imageType);
}
}
this.$emit("getImage",returnImageDatas);
return returnImageDatas;
},
exportCommand(command){
let fileName = 'report_pic.'+command;
if (document.getElementById('picChart')) {
let chartsCanvas = document.getElementById('picChart').querySelectorAll('canvas')[0]
let mime = 'image/png';
if(command === 'jpg'){
mime = 'image/jpg';
}
if (chartsCanvas) {
// toDataURL()canvascanvasbase64
let imageUrl = chartsCanvas && chartsCanvas.toDataURL(mime)
if (navigator.userAgent.indexOf('Trident') > -1) {
// IE11
let arr = imageUrl.split(',')
// atob() 使base64
let bstr = atob(arr[1])
let bstrLen = bstr.length
// Uint8Array, 8 0
let u8arr = new Uint8Array(bstrLen)
while (bstrLen--) {
// charCodeAt() Unicode
u8arr[bstrLen] = bstr.charCodeAt(bstrLen)
}
// msSaveOrOpenBlob Internet
window.navigator.msSaveOrOpenBlob(new Blob([u8arr], {type: mime}), fileName );
} else {
//
let $a = document.createElement('a')
$a.setAttribute('href', imageUrl)
$a.setAttribute('download', fileName)
$a.click()
if (chartsCanvas) {
// toDataURL()canvascanvasbase64
let imageUrl = chartsCanvas && chartsCanvas.toDataURL(mime)
if (navigator.userAgent.indexOf('Trident') > -1) {
// IE11
let arr = imageUrl.split(',')
// atob() 使base64
let bstr = atob(arr[1])
let bstrLen = bstr.length
// Uint8Array, 8 0
let u8arr = new Uint8Array(bstrLen)
while (bstrLen--) {
// charCodeAt() Unicode
u8arr[bstrLen] = bstr.charCodeAt(bstrLen)
}
// msSaveOrOpenBlob Internet
window.navigator.msSaveOrOpenBlob(new Blob([u8arr], {type: mime}), fileName);
} else {
//
let $a = document.createElement('a')
$a.setAttribute('href', imageUrl)
$a.setAttribute('download', fileName)
$a.click()
}
}
},
}
},
}
},
}
</script>
<style scoped>
.ms-test-chart-header {
z-index: 999;
width: 380px;
float: right;
margin-right: 10px;
}
.ms-test-chart-header {
z-index: 999;
width: 380px;
float: right;
margin-right: 10px;
}
.report-alt-ico {
font-size: 15px;
margin: 0px 10px 0px;
color: #8c939d;
}
.report-alt-ico {
font-size: 15px;
margin: 0px 10px 0px;
color: #8c939d;
}
.report-alt-ico:hover {
color: black;
cursor: pointer;
font-size: 18px;
}
.report-alt-ico:hover {
color: black;
cursor: pointer;
font-size: 18px;
}
/deep/ .echarts {
height: calc(100vh / 1.95);
}
/deep/ .echarts {
height: calc(100vh / 1.95);
}
.tip {
float: left;
font-size: 14px;
border-radius: 2px;
border-left: 2px solid #783887;
margin: 0px 20px 0px;
}
.tip {
float: left;
font-size: 14px;
border-radius: 2px;
border-left: 2px solid #783887;
margin: 0px 20px 0px;
}
.ms-row {
padding-top: 10px;
}
.ms-row {
padding-top: 10px;
}
.chart-config {
width: 100%;
}
.chart-config {
width: 100%;
}
/deep/ .el-card__body {
padding: 0px;
}
/deep/ .el-card__body {
padding: 0px;
}
</style>