feat(报表统计): 修复报表统计中已创建的图标类型点击保存却另存为的缺陷

--bug=1014761 --user=宋天阳 [ 报表统计]github
#15634报表统计-项目报表,已创建的报表更改图表类型后,点击保存失败,而是变成了另存为
https://www.tapd.cn/55049933/s/1198644
This commit is contained in:
song-tianyang 2022-07-11 15:13:12 +08:00 committed by TIanyang
parent b459e4736c
commit 2f06d5b95a
6 changed files with 378 additions and 310 deletions

View File

@ -1,9 +1,7 @@
package io.metersphere.reportstatistics.controller; package io.metersphere.reportstatistics.controller;
import com.alibaba.fastjson.JSONArray;
import io.metersphere.base.domain.ReportStatistics; import io.metersphere.base.domain.ReportStatistics;
import io.metersphere.base.domain.ReportStatisticsWithBLOBs; import io.metersphere.base.domain.ReportStatisticsWithBLOBs;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.reportstatistics.dto.ReportStatisticsSaveRequest; import io.metersphere.reportstatistics.dto.ReportStatisticsSaveRequest;
import io.metersphere.reportstatistics.service.ReportStatisticsService; import io.metersphere.reportstatistics.service.ReportStatisticsService;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -32,13 +30,19 @@ public class HistoryReportController {
} }
@PostMapping("/saveReport") @PostMapping("/saveReport")
public ReportStatisticsWithBLOBs saveReport(@RequestBody ReportStatisticsSaveRequest request){ public ReportStatisticsWithBLOBs saveReport(@RequestBody ReportStatisticsSaveRequest request) {
ReportStatisticsWithBLOBs returnData = reportStatisticsService.saveByRequest(request); ReportStatisticsWithBLOBs returnData = reportStatisticsService.saveByRequest(request);
return returnData; return returnData;
} }
@PostMapping("/update")
public ReportStatisticsWithBLOBs update(@RequestBody ReportStatisticsSaveRequest request) {
ReportStatisticsWithBLOBs returnData = reportStatisticsService.update(request);
return returnData;
}
@PostMapping("/updateReport") @PostMapping("/updateReport")
public ReportStatisticsWithBLOBs updateReport(@RequestBody ReportStatisticsSaveRequest request){ public ReportStatisticsWithBLOBs updateReport(@RequestBody ReportStatisticsSaveRequest request) {
ReportStatisticsWithBLOBs returnData = reportStatisticsService.updateByRequest(request); ReportStatisticsWithBLOBs returnData = reportStatisticsService.updateByRequest(request);
return returnData; return returnData;
} }

View File

@ -65,6 +65,11 @@ public class ReportStatisticsService {
return model; return model;
} }
public ReportStatisticsWithBLOBs update(ReportStatisticsSaveRequest request) {
reportStatisticsMapper.updateByPrimaryKeySelective(request);
return request;
}
public int deleteById(String id) { public int deleteById(String id) {
return reportStatisticsMapper.deleteByPrimaryKey(id); return reportStatisticsMapper.deleteByPrimaryKey(id);
} }

View File

@ -1,11 +1,14 @@
<template> <template>
<div class="ms-header"> <div class="ms-header">
<el-row> <el-row>
<div class="ms-div">{{title}}</div> <div class="ms-div">{{ title }}</div>
<div class="ms-header-right"> <div class="ms-header-right">
<el-button type="primary" v-if="isSaveAsButtonShow" size="mini" @click="handleSaveAs" :disabled="readOnly">{{ $t('commons.save_as') }}<i class="el-icon-files el-icon--right"></i></el-button> <el-button type="primary" v-if="isSaveAsButtonShow" size="mini" @click="handleSaveAs" :disabled="readOnly">
<el-button type="primary" v-if="isSaveButtonShow" size="mini" @click="handleSave" :disabled="readOnly">{{ $t('commons.save') }}<i class="el-icon-files el-icon--right"></i></el-button> {{ $t('commons.save_as') }}<i class="el-icon-files el-icon--right"></i></el-button>
<el-button type="" size="mini" @click="handleExport" :disabled="readOnly">{{ $t('report.export') }}<i class="el-icon-download el-icon--right"></i></el-button> <el-button type="primary" v-if="isSaveButtonShow" size="mini" @click="handleSave" :disabled="readOnly">
{{ $t('commons.save') }}<i class="el-icon-files el-icon--right"></i></el-button>
<el-button type="" size="mini" @click="handleExport" :disabled="readOnly">{{ $t('report.export') }}<i
class="el-icon-download el-icon--right"></i></el-button>
<span class="ms-span">|</span> <span class="ms-span">|</span>
<i class="el-icon-close report-alt-ico" @click="close"/> <i class="el-icon-close report-alt-ico" @click="close"/>
</div> </div>
@ -15,17 +18,17 @@
<script> <script>
import {exportPdf, hasPermission} from "@/common/js/utils"; import {exportPdf, hasPermission} from "@/common/js/utils";
import html2canvas from 'html2canvas'; import html2canvas from 'html2canvas';
export default { export default {
name: "ReportHeader", name: "ReportHeader",
components: {}, components: {},
data() { data() {
return {} return {}
}, },
props:{ props: {
title:String, title: String,
historyReportId:String, historyReportId: String,
}, },
created() { created() {
}, },
@ -33,21 +36,21 @@ import {exportPdf, hasPermission} from "@/common/js/utils";
readOnly() { readOnly() {
return !hasPermission('PROJECT_REPORT_ANALYSIS:READ+EXPORT'); return !hasPermission('PROJECT_REPORT_ANALYSIS:READ+EXPORT');
}, },
isSaveAsButtonShow(){ isSaveAsButtonShow() {
if(!this.historyReportId || this.historyReportId === null || this.historyReportId === ''){ if (!this.historyReportId || this.historyReportId === null || this.historyReportId === '') {
return false; return false;
}else { } else {
if(hasPermission('PROJECT_REPORT_ANALYSIS:READ+CREATE')){ if (hasPermission('PROJECT_REPORT_ANALYSIS:READ+CREATE')) {
return true; return true;
}else { } else {
return false; return false;
} }
} }
}, },
isSaveButtonShow(){ isSaveButtonShow() {
if(hasPermission('PROJECT_REPORT_ANALYSIS:READ+UPDATE')){ if (hasPermission('PROJECT_REPORT_ANALYSIS:READ+UPDATE')) {
return true; return true;
}else { } else {
return false; return false;
} }
} }
@ -65,51 +68,55 @@ import {exportPdf, hasPermission} from "@/common/js/utils";
}, 1000); }, 1000);
}); });
}, },
handleSave(){ handleSave() {
this.$emit("saveReport"); if (!this.historyReportId || this.historyReportId === null || this.historyReportId === '') {
this.$emit("selectAndSaveReport");
} else {
this.$emit("updateReport");
}
}, },
handleSaveAs(){ handleSaveAs() {
this.$emit("selectAndSaveReport"); this.$emit("selectAndSaveReport");
}, },
close() { close() {
this.$emit('closePage'); this.$emit('closePage');
}, },
}, },
} }
</script> </script>
<style scoped> <style scoped>
.ms-header { .ms-header {
border-bottom: 1px solid #E6E6E6; border-bottom: 1px solid #E6E6E6;
background-color: #FFF; background-color: #FFF;
} }
.ms-div { .ms-div {
float: left; float: left;
margin-left: 20px; margin-left: 20px;
margin-top: 12px; margin-top: 12px;
} }
.ms-span { .ms-span {
margin: 0px 10px 10px; margin: 0px 10px 10px;
} }
.ms-header-right { .ms-header-right {
float: right; float: right;
/*width: 320px;*/ /*width: 320px;*/
margin-bottom: 10px; margin-bottom: 10px;
margin-top: 10px; margin-top: 10px;
margin-right: 20px; margin-right: 20px;
} }
.report-alt-ico { .report-alt-ico {
font-size: 17px; font-size: 17px;
top: auto; top: auto;
} }
.report-alt-ico:hover { .report-alt-ico:hover {
color: black; color: black;
cursor: pointer; cursor: pointer;
font-size: 18px; font-size: 18px;
} }
</style> </style>

View File

@ -2,7 +2,7 @@
<div> <div>
<el-row type="flex"> <el-row type="flex">
<p class="tip"> <p class="tip">
<span class="ms-span">{{$t('commons.report_statistics.name')}}</span> <span class="ms-span">{{ $t('commons.report_statistics.name') }}</span>
<el-select v-model="reportType" class="ms-col-type" size="mini" style="width: 120px"> <el-select v-model="reportType" class="ms-col-type" size="mini" style="width: 120px">
<el-option :key="t.id" :value="t.id" :label="t.name" v-for="t in reportTypes"/> <el-option :key="t.id" :value="t.id" :label="t.name" v-for="t in reportTypes"/>
</el-select> </el-select>
@ -15,19 +15,24 @@
</transition> </transition>
<!-- 测试用例趋势页面 --> <!-- 测试用例趋势页面 -->
<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="openSaveReportDialog('save')" @selectAndSaveReport="openSaveReportDialog('saveAs')"/> @closePage="close" @updateReport="updateReport"
@selectAndSaveReport="openSaveReportDialog('saveAs')"/>
</template> </template>
<test-analysis-container @initHistoryReportId="initHistoryReportId" ref="testAnalysisContainer"/> <test-analysis-container @initHistoryReportId="initHistoryReportId" ref="testAnalysisContainer"/>
</ms-drawer> </ms-drawer>
<!-- 测试用例分析页面 --> <!-- 测试用例分析页面 -->
<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="openSaveReportDialog('save')" @selectAndSaveReport="openSaveReportDialog('saveAs')"/> @closePage="close"
@updateReport="updateReport"
@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>
@ -44,21 +49,23 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="primary" @click="saveReport">{{$t('commons.confirm')}}</el-button> <el-button type="primary" @click="saveReport">{{ $t('commons.confirm') }}</el-button>
</div> </div>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script> <script>
import ReportCard from "@/business/components/reportstatistics/projectstatistics/ReportCard"; import ReportCard from "@/business/components/reportstatistics/projectstatistics/ReportCard";
import TestAnalysisContainer from "@/business/components/reportstatistics/projectstatistics/track/TestAnalysisContainer"; import TestAnalysisContainer
import MsDrawer from "@/business/components/common/components/MsDrawer"; from "@/business/components/reportstatistics/projectstatistics/track/TestAnalysisContainer";
import ReportHeader from "@/business/components/reportstatistics/base/ReportHeader"; import MsDrawer from "@/business/components/common/components/MsDrawer";
import TestCaseCountContainer from "@/business/components/reportstatistics/projectstatistics/casecount/TestCaseCountContainer"; import ReportHeader from "@/business/components/reportstatistics/base/ReportHeader";
import TestCaseCountContainer
from "@/business/components/reportstatistics/projectstatistics/casecount/TestCaseCountContainer";
export default { export default {
name: "ReportAnalysis", name: "ReportAnalysis",
components: {ReportCard, TestAnalysisContainer, MsDrawer, ReportHeader, TestCaseCountContainer}, components: {ReportCard, TestAnalysisContainer, MsDrawer, ReportHeader, TestCaseCountContainer},
data() { data() {
@ -66,7 +73,7 @@
reportType: "track", reportType: "track",
testCaseTrendDrawer: false, testCaseTrendDrawer: false,
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, dialogFormVisible: false,
form: { form: {
@ -75,17 +82,17 @@
}, },
saveReportRules: { saveReportRules: {
reportName: [ reportName: [
{ required: true, message: this.$t('commons.input_name'), trigger: 'blur' }, {required: true, message: this.$t('commons.input_name'), trigger: 'blur'},
{ min: 1, max: 20, message: '长度不大于20个字符', trigger: 'blur' } {min: 1, max: 20, message: '长度不大于20个字符', trigger: 'blur'}
], ],
} }
} }
}, },
methods: { methods: {
openCard(type) { openCard(type) {
if(type === 'trackTestCase'){ if (type === 'trackTestCase') {
this.testCaseTrendDrawer = true; this.testCaseTrendDrawer = true;
}else if(type === 'countTestCase'){ } else if (type === 'countTestCase') {
this.testCaseCountDrawer = true; this.testCaseCountDrawer = true;
} }
}, },
@ -93,17 +100,26 @@
this.testCaseTrendDrawer = false; this.testCaseTrendDrawer = false;
this.testCaseCountDrawer = false; this.testCaseCountDrawer = false;
}, },
openSaveReportDialog(saveType){ openSaveReportDialog(saveType) {
this.form.saveType = saveType; this.form.saveType = saveType;
this.dialogFormVisible = true; this.dialogFormVisible = true;
}, },
saveReport(){ updateReport() {
if (this.historyReportId) {
if (this.testCaseTrendDrawer) {
this.$refs.testAnalysisContainer.updateReport(this.historyReportId);
} else if (this.testCaseCountDrawer) {
this.$refs.testCaseCountContainer.updateReport(this.historyReportId);
}
}
},
saveReport() {
this.$refs['saveReportRuleForm'].validate((valid) => { this.$refs['saveReportRuleForm'].validate((valid) => {
if (valid) { if (valid) {
if(this.testCaseTrendDrawer){ if (this.testCaseTrendDrawer) {
this.$refs.testAnalysisContainer.saveAndSaveAsReport(this.form.reportName,this.form.saveType); this.$refs.testAnalysisContainer.saveAndSaveAsReport(this.form.reportName, this.form.saveType);
}else if(this.testCaseCountDrawer){ } else if (this.testCaseCountDrawer) {
this.$refs.testCaseCountContainer.saveAndSaveAsReport(this.form.reportName,this.form.saveType); this.$refs.testCaseCountContainer.saveAndSaveAsReport(this.form.reportName, this.form.saveType);
} }
this.form.reportName = ""; this.form.reportName = "";
this.form.saveType = ""; this.form.saveType = "";
@ -113,28 +129,28 @@
} }
}); });
}, },
initHistoryReportId(reportId){ initHistoryReportId(reportId) {
this.historyReportId = reportId; this.historyReportId = reportId;
}, },
handleCloseSaveReportDialog(){ handleCloseSaveReportDialog() {
this.form.reportName = ""; this.form.reportName = "";
this.form.saveType = ""; this.form.saveType = "";
this.dialogFormVisible = false; this.dialogFormVisible = false;
} }
}, },
} }
</script> </script>
<style scoped> <style scoped>
.ms-span { .ms-span {
margin: 10px 10px 0px margin: 10px 10px 0px
} }
.tip { .tip {
float: left; float: left;
font-size: 14px; font-size: 14px;
border-radius: 2px; border-radius: 2px;
border-left: 2px solid #783887; border-left: 2px solid #783887;
margin: 10px 20px 0px; margin: 10px 20px 0px;
} }
</style> </style>

View File

@ -132,7 +132,7 @@ export default {
if (selectTableData) { if (selectTableData) {
this.tableData = selectTableData; this.tableData = selectTableData;
} }
this.$refs.analysisChart.setPieOptionAndBarOption(this.loadOption,this.pieOption); this.$refs.analysisChart.setPieOptionAndBarOption(this.loadOption, this.pieOption);
this.loading = false; this.loading = false;
this.$refs.analysisChart.generateOption(this.chartType); this.$refs.analysisChart.generateOption(this.chartType);
}, },
@ -143,6 +143,24 @@ export default {
this.options.order = order; this.options.order = order;
this.filterCharts(this.options); this.filterCharts(this.options);
}, },
updateReport(reportId) {
let obj = {};
obj.id = reportId;
obj.projectId = getCurrentProjectID();
obj.selectOption = JSON.stringify(this.options);
let dataOptionObj = {
loadOption: this.loadOption,
pieOption: this.pieOption,
tableData: this.tableData,
chartType: this.chartType,
};
obj.dataOption = JSON.stringify(dataOptionObj);
obj.reportType = 'TEST_CASE_COUNT';
this.$post("/history/report/update", obj, response => {
this.$alert(this.$t('commons.save_success'));
this.$refs.historyReport.initReportData();
});
},
saveReport(reportName) { saveReport(reportName) {
let obj = {}; let obj = {};
obj.name = reportName; obj.name = reportName;

View File

@ -9,7 +9,8 @@
</el-aside> </el-aside>
<el-main class="ms-main"> <el-main class="ms-main">
<div> <div>
<test-analysis-chart @hidePage="hidePage" @orderCharts="orderCharts" ref="analysisChart" :load-option="loadOption"/> <test-analysis-chart @hidePage="hidePage" @orderCharts="orderCharts" ref="analysisChart"
:load-option="loadOption"/>
</div> </div>
<div class="ms-row" v-if="!isHide"> <div class="ms-row" v-if="!isHide">
<test-analysis-table :tableData="tableData"/> <test-analysis-table :tableData="tableData"/>
@ -24,14 +25,14 @@
</template> </template>
<script> <script>
import TestAnalysisChart from "./chart/TestAnalysisChart"; import TestAnalysisChart from "./chart/TestAnalysisChart";
import TestAnalysisTable from "./table/TestAnalysisTable"; import TestAnalysisTable from "./table/TestAnalysisTable";
import TestAnalysisFilter from "./filter/TestAnalysisFilter"; import TestAnalysisFilter from "./filter/TestAnalysisFilter";
import {exportPdf, getCurrentProjectID} from "@/common/js/utils"; import {exportPdf, getCurrentProjectID} from "@/common/js/utils";
import html2canvas from 'html2canvas'; import html2canvas from 'html2canvas';
import HistoryReportData from "../../base/HistoryReportData"; import HistoryReportData from "../../base/HistoryReportData";
export default { export default {
name: "TestAnalysisContainer", name: "TestAnalysisContainer",
components: {TestAnalysisChart, TestAnalysisTable, TestAnalysisFilter, HistoryReportData}, components: {TestAnalysisChart, TestAnalysisTable, TestAnalysisFilter, HistoryReportData},
data() { data() {
@ -76,7 +77,7 @@
this.$post(' /report/test/analysis/getReport', opt, response => { this.$post(' /report/test/analysis/getReport', opt, response => {
let data = response.data.chartDTO; let data = response.data.chartDTO;
let tableDTOs = response.data.tableDTOs; let tableDTOs = response.data.tableDTOs;
this.initPic(data,tableDTOs); this.initPic(data, tableDTOs);
}); });
}, },
filterCharts(opt) { filterCharts(opt) {
@ -86,6 +87,23 @@
this.options.order = order; this.options.order = order;
this.filterCharts(this.options); this.filterCharts(this.options);
}, },
updateReport(reportId) {
let obj = {};
obj.id = reportId;
obj.projectId = getCurrentProjectID();
obj.selectOption = JSON.stringify(this.options);
let dataOptionObj = {
loadOption: this.loadOption,
pieOption: this.pieOption,
tableData: this.tableData,
};
obj.dataOption = JSON.stringify(dataOptionObj);
obj.reportType = 'TEST_CASE_ANALYSIS';
this.$post("/history/report/update", obj, response => {
this.$alert(this.$t('commons.save_success'));
this.$refs.historyReport.initReportData();
});
},
saveReport(reportName) { saveReport(reportName) {
let obj = {}; let obj = {};
obj.name = reportName; obj.name = reportName;
@ -103,7 +121,7 @@
this.$refs.historyReport.initReportData(); this.$refs.historyReport.initReportData();
}); });
}, },
initPic(loadOptionParam,tableData){ initPic(loadOptionParam, tableData) {
this.loading = true; this.loading = true;
if (loadOptionParam) { if (loadOptionParam) {
this.loadOption.legend = loadOptionParam.legend; this.loadOption.legend = loadOptionParam.legend;
@ -121,20 +139,20 @@
} }
this.loading = false; this.loading = false;
}, },
selectReport(selectId){ selectReport(selectId) {
if(selectId){ if (selectId) {
this.loading = true; this.loading = true;
let paramObj = { let paramObj = {
id:selectId id: selectId
} }
this.$post('/history/report/selectById',paramObj, response => { this.$post('/history/report/selectById', paramObj, response => {
let reportData = response.data; let reportData = response.data;
if(reportData){ if (reportData) {
if(reportData.dataOption){ if (reportData.dataOption) {
let dataOptionObj = JSON.parse(reportData.dataOption); let dataOptionObj = JSON.parse(reportData.dataOption);
this.initPic(dataOptionObj.loadOption,dataOptionObj.pieOption,dataOptionObj.tableData); this.initPic(dataOptionObj.loadOption, dataOptionObj.pieOption, dataOptionObj.tableData);
} }
if(reportData.selectOption){ if (reportData.selectOption) {
let selectOptionObj = JSON.parse(reportData.selectOption); let selectOptionObj = JSON.parse(reportData.selectOption);
this.$refs.analysisFilter.initSelectOption(selectOptionObj); this.$refs.analysisFilter.initSelectOption(selectOptionObj);
} }
@ -143,34 +161,34 @@
}, (error) => { }, (error) => {
this.loading = false; this.loading = false;
}); });
this.$emit('initHistoryReportId',selectId); this.$emit('initHistoryReportId', selectId);
} }
}, },
removeHistoryReportId(){ removeHistoryReportId() {
this.$emit('initHistoryReportId',""); this.$emit('initHistoryReportId', "");
}, },
selectAndSaveReport(reportName){ selectAndSaveReport(reportName) {
let opt = this.$refs.analysisFilter.getOption(); let opt = this.$refs.analysisFilter.getOption();
this.options = opt; this.options = opt;
this.saveReport(reportName); this.saveReport(reportName);
}, },
saveAndSaveAsReport(reportName,saveType){ saveAndSaveAsReport(reportName, saveType) {
if(saveType === 'save'){ if (saveType === 'save') {
this.saveReport(reportName); this.saveReport(reportName);
}else if(saveType === 'saveAs'){ } else if (saveType === 'saveAs') {
this.selectAndSaveReport(reportName); this.selectAndSaveReport(reportName);
} }
} }
}, },
} }
</script> </script>
<style scoped> <style scoped>
.ms-row { .ms-row {
padding-top: 10px; padding-top: 10px;
} }
/deep/ .el-main { /deep/ .el-main {
padding: 0px 20px 0px; padding: 0px 20px 0px;
} }
</style> </style>