parent
265893012f
commit
ea5a4ca0ae
|
@ -3,9 +3,11 @@ package io.metersphere.api.service;
|
|||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.api.dto.automation.APIScenarioReportResult;
|
||||
import io.metersphere.api.dto.share.*;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.base.mapper.ext.ExtApiScenarioReportMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtShareInfoMapper;
|
||||
import io.metersphere.commons.constants.ProjectApplicationType;
|
||||
import io.metersphere.commons.constants.ShareType;
|
||||
|
@ -61,6 +63,9 @@ public class ShareInfoService {
|
|||
@Lazy
|
||||
@Resource
|
||||
TestPlanMapper testPlanMapper;
|
||||
@Resource
|
||||
private ExtApiScenarioReportMapper extApiScenarioReportMapper;
|
||||
|
||||
|
||||
public List<ApiDocumentInfoDTO> findApiDocumentSimpleInfoByRequest(ApiDocumentRequest request) {
|
||||
if (this.isParamLegitimacy(request)) {
|
||||
|
@ -547,6 +552,14 @@ public class ShareInfoService {
|
|||
projectId = testPlan.getProjectId();
|
||||
};
|
||||
|
||||
}
|
||||
if(shareInfo.getShareType().equals("API_REPORT")){
|
||||
type = ProjectApplicationType.API_SHARE_REPORT_TIME.toString();
|
||||
APIScenarioReportResult reportResult = extApiScenarioReportMapper.get(shareInfo.getCustomData());
|
||||
if (reportResult != null){
|
||||
projectId = reportResult.getProjectId();
|
||||
};
|
||||
|
||||
}
|
||||
if(StringUtils.isBlank(type)|| Strings.isBlank(projectId)){
|
||||
millisCheck(System.currentTimeMillis() - shareInfo.getUpdateTime() ,1000 * 60 * 60 * 24,shareInfo.getId());
|
||||
|
|
|
@ -2,5 +2,6 @@ package io.metersphere.commons.constants;
|
|||
|
||||
public enum ProjectApplicationType {
|
||||
TRACK_SHARE_REPORT_TIME,
|
||||
PERFORMANCE_SHARE_REPORT_TIME
|
||||
PERFORMANCE_SHARE_REPORT_TIME,
|
||||
API_SHARE_REPORT_TIME
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ public class ShiroUtils {
|
|||
filterChainDefinitionMap.put("/share/**", "anon");
|
||||
filterChainDefinitionMap.put("/sharePlanReport", "anon");
|
||||
filterChainDefinitionMap.put("/sharePerformanceReport", "anon");
|
||||
filterChainDefinitionMap.put("/shareApiReport", "anon");
|
||||
|
||||
filterChainDefinitionMap.put("/system/theme", "anon");
|
||||
filterChainDefinitionMap.put("/system/save/baseurl/**", "anon");
|
||||
|
|
|
@ -46,4 +46,9 @@ public class IndexController {
|
|||
public String sharePerformanceRedirect() {
|
||||
return "share-performance-report.html";
|
||||
}
|
||||
|
||||
@GetMapping(value = "/shareApiReport")
|
||||
public String shareApiRedirect() {
|
||||
return "share-api-report.html";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -157,7 +157,7 @@ public class ShareController {
|
|||
|
||||
@GetMapping("/api/scenario/report/get/{shareId}/{reportId}")
|
||||
public APIScenarioReportResult get(@PathVariable String shareId, @PathVariable String reportId) {
|
||||
// shareInfoService.scenarioReportValidate(shareId, reportId);
|
||||
shareInfoService.validate(shareId, reportId);
|
||||
return apiScenarioReportService.get(reportId);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
DROP PROCEDURE IF EXISTS project_api_appl;
|
||||
DELIMITER //
|
||||
CREATE PROCEDURE project_api_appl()
|
||||
BEGIN
|
||||
#声明结束标识
|
||||
DECLARE end_flag int DEFAULT 0;
|
||||
|
||||
DECLARE projectId varchar(64);
|
||||
|
||||
#声明游标 group_curosr
|
||||
DECLARE project_curosr CURSOR FOR SELECT DISTINCT id FROM project;
|
||||
|
||||
#设置终止标志
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET end_flag=1;
|
||||
|
||||
#打开游标
|
||||
OPEN project_curosr;
|
||||
#获取当前游标指针记录,取出值赋给自定义的变量
|
||||
FETCH project_curosr INTO projectId;
|
||||
#遍历游标
|
||||
REPEAT
|
||||
#利用取到的值进行数据库的操作
|
||||
INSERT INTO project_application (project_id, type, type_value)
|
||||
VALUES (projectId, 'API_SHARE_REPORT_TIME', '24H');
|
||||
# 将游标中的值再赋值给变量,供下次循环使用
|
||||
FETCH project_curosr INTO projectId;
|
||||
UNTIL end_flag END REPEAT;
|
||||
|
||||
#关闭游标
|
||||
close project_curosr;
|
||||
|
||||
END
|
||||
//
|
||||
DELIMITER ;
|
||||
|
||||
CALL project_api_appl();
|
||||
DROP PROCEDURE IF EXISTS project_api_appl;
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<ms-api-report :report-id="reportId"></ms-api-report>
|
||||
<ms-api-report :report-id="reportIdValue" :share-id="shareId" :is-share="isShare" :is-plan="isPlanReport" :is-template="false"></ms-api-report>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -7,13 +7,30 @@ import MsApiReport from "@/business/components/api/automation/report/ApiReportDe
|
|||
export default {
|
||||
name: "ApiReportView",
|
||||
components: {MsApiReport},
|
||||
computed: {
|
||||
reportId:function (){
|
||||
return this.$route.params.reportId
|
||||
}
|
||||
},
|
||||
props: {
|
||||
reportId:String,
|
||||
isShare: Boolean,
|
||||
shareId: String,
|
||||
isPlanReport: Boolean,
|
||||
},
|
||||
computed: {
|
||||
reportIdByPath:function (){
|
||||
if(this.$route){
|
||||
return this.$route.params.reportId
|
||||
}else{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
reportIdValue:'',
|
||||
}
|
||||
},
|
||||
created() {
|
||||
console.log(this.reportId)
|
||||
if(!this.reportIdValue){
|
||||
this.reportIdValue = this.reportIdByPath ? this.reportIdByPath:this.reportId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,9 +23,30 @@
|
|||
<el-button v-if="!isPlan && (!debug || exportFlag) && !isTemplate" v-permission="['PROJECT_API_REPORT:READ+EXPORT']" :disabled="isReadOnly" class="export-button" plain type="primary" size="mini" @click="handleExport(report.name)" style="margin-right: 10px">
|
||||
{{ $t('test_track.plan_view.export_report') }}
|
||||
</el-button>
|
||||
<el-popover
|
||||
v-if="!isPlan && (!debug || exportFlag) && !isTemplate"
|
||||
v-permission="['PROJECT_PERFORMANCE_REPORT:READ+EXPORT']"
|
||||
style="margin-right: 10px;float: right;"
|
||||
placement="bottom"
|
||||
width="300">
|
||||
<p>{{ shareUrl }}</p>
|
||||
<span style="color: red;float: left;margin-left: 10px;" v-if="application.typeValue">{{
|
||||
$t('commons.validity_period')+application.typeValue
|
||||
}}</span>
|
||||
<div style="text-align: right; margin: 0">
|
||||
<el-button type="primary" size="mini" :disabled="!shareUrl"
|
||||
v-clipboard:copy="shareUrl">{{ $t("commons.copy") }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-button slot="reference" :disabled="isReadOnly" type="danger" plain size="mini"
|
||||
@click="handleShare(report)">
|
||||
{{ $t('test_track.plan_view.share_report') }}
|
||||
</el-button>
|
||||
</el-popover>
|
||||
<el-button v-if="showCancelButton" class="export-button" plain size="mini" @click="returnView()" >
|
||||
{{$t('commons.cancel')}}
|
||||
</el-button>
|
||||
|
||||
</el-col>
|
||||
</el-row>
|
||||
</header>
|
||||
|
@ -33,6 +54,9 @@
|
|||
|
||||
<script>
|
||||
|
||||
import {generateShareInfoWithExpired} from "@/network/share";
|
||||
import {getCurrentProjectID} from "@/common/js/utils";
|
||||
|
||||
export default {
|
||||
name: "MsApiReportViewHeader",
|
||||
props: {
|
||||
|
@ -73,6 +97,8 @@ export default {
|
|||
return {
|
||||
isReadOnly: false,
|
||||
nameIsEdit: false,
|
||||
shareUrl: "",
|
||||
application:{}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
@ -91,7 +117,38 @@ export default {
|
|||
},
|
||||
returnView(){
|
||||
this.$router.push('/api/automation/report');
|
||||
}
|
||||
},
|
||||
handleShare(report) {
|
||||
this.getProjectApplication();
|
||||
let pram = {};
|
||||
pram.customData = report.id;
|
||||
pram.shareType = 'API_REPORT';
|
||||
generateShareInfoWithExpired(pram, (data) => {
|
||||
let thisHost = window.location.host;
|
||||
this.shareUrl = thisHost + "/shareApiReport" + data.shareUrl;
|
||||
});
|
||||
},
|
||||
getProjectApplication(){
|
||||
this.$get('/project_application/get/' + getCurrentProjectID()+"/API_SHARE_REPORT_TIME", res => {
|
||||
if(res.data){
|
||||
let quantity = res.data.typeValue.substring(0, res.data.typeValue.length - 1);
|
||||
let unit = res.data.typeValue.substring(res.data.typeValue.length - 1);
|
||||
if(unit==='H'){
|
||||
res.data.typeValue = quantity+this.$t('commons.date_unit.hour');
|
||||
}else
|
||||
if(unit==='D'){
|
||||
res.data.typeValue = quantity+this.$t('commons.date_unit.day');
|
||||
}else
|
||||
if(unit==='M'){
|
||||
res.data.typeValue = quantity+this.$t('commons.date_unit.month');
|
||||
}else
|
||||
if(unit==='Y'){
|
||||
res.data.typeValue = quantity+this.$t('commons.date_unit.year');
|
||||
}
|
||||
this.application = res.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -156,7 +156,6 @@ export default {
|
|||
};
|
||||
},
|
||||
created() {
|
||||
console.log("看看是不是这页面")
|
||||
this.$get('/api/definition/follow/' + this.basisData.id, response => {
|
||||
this.basisData.follows = response.data;
|
||||
for (let i = 0; i < response.data.length; i++) {
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
</div>
|
||||
<el-button slot="reference" :disabled="isReadOnly" type="danger" plain size="mini"
|
||||
@click="handleShare(report)">
|
||||
{{ $t('分享报告') }}
|
||||
{{ $t('test_track.plan_view.share_report') }}
|
||||
</el-button>
|
||||
</el-popover>
|
||||
<el-button :disabled="report.status !== 'Completed'" type="default" plain
|
||||
|
|
|
@ -62,6 +62,8 @@
|
|||
</app-manage-item>
|
||||
<timing-item ref="apiTimingItem" :choose.sync="form.cleanApiReport" :expr.sync="form.cleanApiReportExpr"
|
||||
@chooseChange="chooseChange" :title="$t('project.timing_clean_api_report')"/>
|
||||
<timing-item ref="trackTimingItem" :choose.sync="application.shareReport" :expr.sync="application.typeValue" :share-link="true" :unit-options="applyUnitOptions"
|
||||
@chooseChange="chooseChangeApply" :title="$t('report.report_sharing_link')"/>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :span="8" :offset="4">
|
||||
|
|
|
@ -204,7 +204,6 @@ export default {
|
|||
this.currentRow = row;
|
||||
},
|
||||
handleDelete(row) {
|
||||
console.log(row);
|
||||
this.$confirm(this.$t('project.file_delete_tip', [row.name]), '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
cancelButtonText: this.$t('commons.cancel'),
|
||||
|
|
|
@ -2301,6 +2301,7 @@ export default {
|
|||
test_detail: "Test detail",
|
||||
failure_case: "Failure case",
|
||||
export_report: "Export Report",
|
||||
share_report: "Share Report",
|
||||
no_case_relevance: "No related use cases",
|
||||
automatically_update_status: "Auto update status",
|
||||
allow_associated_repetitive_cases: "Repetitive Case",
|
||||
|
|
|
@ -2306,6 +2306,7 @@ export default {
|
|||
test_detail: "测试详情",
|
||||
failure_case: "失败用例",
|
||||
export_report: "导出报告",
|
||||
share_report: "分享报告",
|
||||
no_case_relevance: "没有关联用例",
|
||||
automatically_update_status: "自动更新状态",
|
||||
automatically_update_status_tip: "当功能用例关联的接口或性能用例在测试计划执行后,自动更新功能用例的状态",
|
||||
|
|
|
@ -2305,6 +2305,7 @@ export default {
|
|||
test_detail: "測試詳情",
|
||||
failure_case: "失敗用例",
|
||||
export_report: "導出報告",
|
||||
share_report: "分享報告",
|
||||
no_case_relevance: "沒有關聯用例",
|
||||
automatically_update_status: "自動更新狀態",
|
||||
automatically_update_status_tip: "當功能用例關聯的接口或性能用例在測試計劃執行後,自動更新功能用例的狀態",
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
import Vue from 'vue';
|
||||
import ElementUI, {Button, Card, Col, Form, FormItem, Input, Main, Popover, Row, Table, TableColumn} from 'element-ui';
|
||||
import '@/assets/theme/index.css';
|
||||
import '@/common/css/menu-header.css';
|
||||
import '@/common/css/main.css';
|
||||
import i18n from "@/i18n/i18n";
|
||||
import chart from "@/common/js/chart";
|
||||
import filters from "@/common/js/filter";
|
||||
import icon from "@/common/js/icon";
|
||||
import message from "@/common/js/message";
|
||||
import ajax from "@/common/js/ajax";
|
||||
|
||||
|
||||
function apiReportUse(id, template) {
|
||||
Vue.use(ElementUI, {
|
||||
i18n: (key, value) => i18n.t(key, value)
|
||||
});
|
||||
|
||||
Vue.use(Row);
|
||||
Vue.use(Col);
|
||||
Vue.use(Form);
|
||||
Vue.use(FormItem);
|
||||
Vue.use(Input);
|
||||
Vue.use(Button);
|
||||
Vue.use(chart);
|
||||
Vue.use(Main);
|
||||
Vue.use(Card);
|
||||
Vue.use(TableColumn);
|
||||
Vue.use(Table);
|
||||
Vue.use(filters);
|
||||
Vue.use(icon);
|
||||
Vue.use(message);
|
||||
Vue.use(ajax);
|
||||
Vue.use(Popover);
|
||||
|
||||
new Vue({
|
||||
el: id,
|
||||
i18n,
|
||||
render: h => h(template)
|
||||
});
|
||||
}
|
||||
|
||||
export default apiReportUse;
|
|
@ -0,0 +1,36 @@
|
|||
<template>
|
||||
<ms-api-report :report-id="reportId" :share-id="shareId" :is-share="isShare" :is-plan="true" ></ms-api-report>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getShareId} from "@/common/js/utils";
|
||||
import {getShareInfo} from "@/network/share";
|
||||
import MsApiReport from "@/business/components/api/automation/report/ApiReportDetail";
|
||||
|
||||
export default {
|
||||
name: "ShareApiReportTemplate",
|
||||
components: {MsApiReport},
|
||||
data() {
|
||||
return {
|
||||
reportId: '',
|
||||
shareId: '',
|
||||
isShare: true,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.shareId = getShareId();
|
||||
getShareInfo(this.shareId, (data) => {
|
||||
if (!data) {
|
||||
this.$error('连接已失效,请重新获取!');
|
||||
return;
|
||||
}
|
||||
if (data.shareType === 'API_REPORT') {
|
||||
this.reportId = data.customData;
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="shortcut icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title>Api Report</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="shareApiReport"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,4 @@
|
|||
import ShareApiReportTemplate from "@/template/report/api/share/ShareApiReportTemplate";
|
||||
import apiReportUse from "@/template/report/api/apiReportUse";
|
||||
|
||||
apiReportUse('#shareApiReport', ShareApiReportTemplate);
|
|
@ -44,6 +44,11 @@ module.exports = {
|
|||
template: "src/template/report/performance/share/share-performance-report.html",
|
||||
filename: "share-performance-report.html",
|
||||
},
|
||||
shareApiReport: {
|
||||
entry: "src/template/report/api/share/share-api-report.js",
|
||||
template: "src/template/report/api/share/share-api-report.html",
|
||||
filename: "share-api-report.html",
|
||||
},
|
||||
enterpriseReport: {
|
||||
entry: "src/template/enterprise/share/share-enterprise-report.js",
|
||||
template: "src/template/enterprise/share/share-enterprise-report.html",
|
||||
|
|
Loading…
Reference in New Issue