Merge branch 'master' of https://github.com/metersphere/metersphere
This commit is contained in:
commit
f825b009d7
|
@ -12,7 +12,6 @@ import io.metersphere.commons.utils.PageUtils;
|
|||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.controller.request.QueryScheduleRequest;
|
||||
import io.metersphere.dto.LicenseDTO;
|
||||
import io.metersphere.dto.ScheduleDao;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
|
|
|
@ -20,7 +20,6 @@ import io.metersphere.commons.constants.ScheduleType;
|
|||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.controller.request.QueryScheduleRequest;
|
||||
import io.metersphere.dto.LicenseDTO;
|
||||
import io.metersphere.dto.ScheduleDao;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.job.sechedule.ApiTestJob;
|
||||
|
|
|
@ -5,7 +5,6 @@ import io.metersphere.commons.constants.UserSource;
|
|||
import io.metersphere.commons.user.SessionUser;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.controller.request.LoginRequest;
|
||||
import io.metersphere.dto.LicenseDTO;
|
||||
import io.metersphere.service.UserService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
|
@ -67,10 +66,4 @@ public class LoginController {
|
|||
public String getDefaultLanguage() {
|
||||
return userService.getDefaultLanguage();
|
||||
}
|
||||
|
||||
@GetMapping("/api/license/valid")
|
||||
public LicenseDTO valid() {
|
||||
return userService.validateLicense();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
package io.metersphere.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class LicenseDTO implements Serializable {
|
||||
|
||||
private String status;
|
||||
|
||||
private LicenseInfoDTO license;
|
||||
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package io.metersphere.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class LicenseInfoDTO implements Serializable {
|
||||
// 客户名称
|
||||
private String corporation;
|
||||
// 授权截止时间
|
||||
private String expired;
|
||||
//产品名称
|
||||
private String product;
|
||||
//产品版本
|
||||
private String edition;
|
||||
//icense版本
|
||||
private String licenseVersion;
|
||||
//授权数量
|
||||
private int licenseCount;
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package io.metersphere.service;
|
||||
|
||||
import io.metersphere.dto.LicenseDTO;
|
||||
|
||||
public interface LicenseService {
|
||||
|
||||
public LicenseDTO valid();
|
||||
|
||||
public LicenseDTO addValidLicense(String reqLicenseCode);
|
||||
}
|
|
@ -10,7 +10,6 @@ import io.metersphere.commons.constants.UserStatus;
|
|||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.user.SessionUser;
|
||||
import io.metersphere.commons.utils.CodingUtil;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.controller.ResultHolder;
|
||||
import io.metersphere.controller.request.LoginRequest;
|
||||
|
@ -20,7 +19,6 @@ import io.metersphere.controller.request.member.QueryMemberRequest;
|
|||
import io.metersphere.controller.request.member.UserRequest;
|
||||
import io.metersphere.controller.request.organization.AddOrgMemberRequest;
|
||||
import io.metersphere.controller.request.organization.QueryOrgMemberRequest;
|
||||
import io.metersphere.dto.LicenseDTO;
|
||||
import io.metersphere.dto.UserDTO;
|
||||
import io.metersphere.dto.UserRoleDTO;
|
||||
import io.metersphere.i18n.Translator;
|
||||
|
@ -36,6 +34,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -591,12 +590,4 @@ public class UserService {
|
|||
public List<User> searchUser(String condition) {
|
||||
return extUserMapper.searchUser(condition);
|
||||
}
|
||||
|
||||
public LicenseDTO validateLicense() {
|
||||
LicenseService licenseService = CommonBeanFactory.getBean(LicenseService.class);
|
||||
if (licenseService != null) {
|
||||
return licenseService.valid();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 321c869938357e8c2253e5bd86c963828664ae23
|
||||
Subproject commit e51e5704f9d7fbfb030a8a7d67d0094a9f36c23d
|
|
@ -32,7 +32,7 @@
|
|||
import {saveLocalStorage} from "../common/js/utils";
|
||||
|
||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||
const header = requireComponent("./license/LicenseMessage.vue");
|
||||
const header = requireComponent.keys().length > 0 ? requireComponent("./license/LicenseMessage.vue") : {};
|
||||
|
||||
export default {
|
||||
name: 'app',
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
<template>
|
||||
<el-card>
|
||||
<div class="report-title title">接口测试报告</div>
|
||||
<ms-metric-chart :content="content" :totalTime="totalTime"/>
|
||||
<div class="scenario-result" v-for="(scenario, index) in content.scenarios" :key="index" :scenario="scenario">
|
||||
<div>
|
||||
<el-card >
|
||||
<template v-slot:header>
|
||||
{{$t('api_report.scenario_name')}}:{{scenario.name}}
|
||||
</template>
|
||||
<div class="ms-border" v-for="(request, index) in scenario.requestResults" :key="index" :request="request">
|
||||
|
||||
<div class="request-left">
|
||||
<api-report-reqest-header-item :title="request.name">
|
||||
<span class="url"> {{request.url}}</span>
|
||||
</api-report-reqest-header-item>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="request-right">
|
||||
|
||||
<api-report-reqest-header-item :title="$t('api_test.request.method')">
|
||||
<span class="method"> {{request.method}}</span>
|
||||
</api-report-reqest-header-item>
|
||||
|
||||
<api-report-reqest-header-item :title="$t('api_report.response_time')">
|
||||
{{request.responseResult.responseTime}}
|
||||
</api-report-reqest-header-item>
|
||||
|
||||
<api-report-reqest-header-item :title="$t('api_report.latency')">
|
||||
{{request.responseResult.latency}} ms
|
||||
</api-report-reqest-header-item>
|
||||
|
||||
<api-report-reqest-header-item :title="$t('api_report.request_size')">
|
||||
{{request.requestSize}} bytes
|
||||
</api-report-reqest-header-item>
|
||||
|
||||
<api-report-reqest-header-item :title="$t('api_report.response_size')">
|
||||
{{request.responseResult.latency}} ms
|
||||
</api-report-reqest-header-item>
|
||||
|
||||
<api-report-reqest-header-item :title="$t('api_report.error')">
|
||||
{{request.responseResult.responseSize}} bytes
|
||||
</api-report-reqest-header-item>
|
||||
|
||||
<api-report-reqest-header-item :title="$t('api_report.assertions')">
|
||||
{{request.passAssertions + " / " + request.totalAssertions}}
|
||||
</api-report-reqest-header-item>
|
||||
|
||||
<api-report-reqest-header-item :title="$t('api_report.response_code')">
|
||||
{{request.responseResult.responseCode}}
|
||||
</api-report-reqest-header-item>
|
||||
|
||||
<api-report-reqest-header-item :title="$t('api_report.result')">
|
||||
<el-tag size="mini" type="success" v-if="request.success">
|
||||
{{$t('api_report.success')}}
|
||||
</el-tag>
|
||||
<el-tag size="mini" type="danger" v-else>
|
||||
{{$t('api_report.fail')}}
|
||||
</el-tag>
|
||||
</api-report-reqest-header-item>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsScenarioResult from "./components/ScenarioResult";
|
||||
import MsRequestResultTail from "./components/RequestResultTail";
|
||||
import ApiReportReqestHeaderItem from "./ApiReportReqestHeaderItem";
|
||||
import MsMetricChart from "./components/MetricChart";
|
||||
export default {
|
||||
name: "MsApiReportExport",
|
||||
components: {MsMetricChart, ApiReportReqestHeaderItem, MsRequestResultTail, MsScenarioResult},
|
||||
props: {
|
||||
content: Object,
|
||||
totalTime: Number
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.scenario-result {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.method {
|
||||
color: #1E90FF;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.request-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.request-left {
|
||||
float: left;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.ms-border {
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.report-title {
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
height: 50px;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.url {
|
||||
color: #409EFF;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
padding: 10px;
|
||||
padding: 30px;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,31 @@
|
|||
<template>
|
||||
<div class="item">
|
||||
<div class="item-title">
|
||||
{{title}}
|
||||
</div>
|
||||
<div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "ApiReportReqestHeaderItem",
|
||||
props: {title: String}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.item {
|
||||
width: 120px;
|
||||
height: 50px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -9,10 +9,10 @@
|
|||
<span>{{ report.projectName }} / </span>
|
||||
<router-link :to="path">{{ report.testName }}</router-link>
|
||||
<span class="time">{{ report.createTime | timestampFormatDate }}</span>
|
||||
<!--<el-button plain type="primary" size="mini" @click="handleExport(report.name)"
|
||||
<el-button class="export-button" plain type="primary" size="mini" @click="handleExport(report.name)"
|
||||
style="margin-left: 1200px">
|
||||
{{$t('test_track.plan_view.export_report')}}
|
||||
</el-button>-->
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</header>
|
||||
|
@ -36,6 +36,7 @@
|
|||
<ms-request-result-tail v-if="isRequestResult" :request="request" :scenario-name="scenarioName"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<ms-api-report-export v-if="reportExportVisible" id="apiTestReport" :content="content" :total-time="totalTime"/>
|
||||
</main>
|
||||
</section>
|
||||
</el-card>
|
||||
|
@ -52,10 +53,14 @@ import MsMetricChart from "./components/MetricChart";
|
|||
import MsScenarioResults from "./components/ScenarioResults";
|
||||
import MsContainer from "@/business/components/common/components/MsContainer";
|
||||
import MsMainContainer from "@/business/components/common/components/MsMainContainer";
|
||||
import MsApiReportExport from "./ApiReportExport";
|
||||
import {exportPdf} from "../../../../common/js/utils";
|
||||
import html2canvas from "html2canvas";
|
||||
|
||||
export default {
|
||||
name: "MsApiReportView",
|
||||
components: {
|
||||
MsApiReportExport,
|
||||
MsMainContainer,
|
||||
MsContainer, MsScenarioResults, MsRequestResultTail, MsMetricChart, MsScenarioResult, MsRequestResult
|
||||
},
|
||||
|
@ -70,6 +75,7 @@ export default {
|
|||
isRequestResult: false,
|
||||
request: {},
|
||||
scenarioName: null,
|
||||
reportExportVisible: false
|
||||
}
|
||||
},
|
||||
activated() {
|
||||
|
@ -139,6 +145,26 @@ export default {
|
|||
this.request = requestResult.request;
|
||||
this.scenarioName = requestResult.scenarioName;
|
||||
});
|
||||
},
|
||||
handleExport(name) {
|
||||
this.loading = true;
|
||||
this.reportExportVisible = true;
|
||||
let reset = this.exportReportReset;
|
||||
|
||||
this.$nextTick(function () {
|
||||
setTimeout(() => {
|
||||
html2canvas(document.getElementById('apiTestReport'), {
|
||||
scale: 2
|
||||
}).then(function(canvas) {
|
||||
exportPdf(name, [canvas]);
|
||||
reset();
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
},
|
||||
exportReportReset() {
|
||||
this.reportExportVisible = false;
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -170,30 +196,36 @@ export default {
|
|||
</style>
|
||||
|
||||
<style scoped>
|
||||
.report-container {
|
||||
|
||||
.report-container {
|
||||
height: calc(100vh - 155px);
|
||||
min-height: 600px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.report-header {
|
||||
.report-header {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.report-header a {
|
||||
.report-header a {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.report-header .time {
|
||||
.report-header .time {
|
||||
color: #909399;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.report-container .fail {
|
||||
.report-container .fail {
|
||||
color: #F56C6C;
|
||||
}
|
||||
}
|
||||
|
||||
.report-container .is-active .fail {
|
||||
.report-container .is-active .fail {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.export-button {
|
||||
float: right;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -88,18 +88,24 @@
|
|||
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
],
|
||||
driver: [
|
||||
{required: true, message: this.$t('commons.input_name'), trigger: 'blur'},
|
||||
{required: true, message: this.$t('commons.cannot_be_null'), trigger: 'blur'},
|
||||
],
|
||||
password: [
|
||||
{max: 200, message: this.$t('commons.input_limit', [0, 200]), trigger: 'blur'}
|
||||
],
|
||||
dbUrl: [
|
||||
{required: true, message: this.$t('commons.input_name'), trigger: 'blur'},
|
||||
{required: true, message: this.$t('commons.cannot_be_null'), trigger: 'blur'},
|
||||
{max: 500, message: this.$t('commons.input_limit', [0, 500]), trigger: 'blur'}
|
||||
],
|
||||
username: [
|
||||
{required: true, message: this.$t('commons.input_name'), trigger: 'blur'},
|
||||
{required: true, message: this.$t('commons.cannot_be_null'), trigger: 'blur'},
|
||||
{max: 200, message: this.$t('commons.input_limit', [0, 200]), trigger: 'blur'}
|
||||
],
|
||||
poolMax: [
|
||||
{required: true, message: this.$t('commons.cannot_be_null'), trigger: 'blur'},
|
||||
],
|
||||
timeout: [
|
||||
{required: true, message: this.$t('commons.cannot_be_null'), trigger: 'blur'},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,28 +66,21 @@
|
|||
</div>
|
||||
|
||||
<div class="report-export" v-show="reportExportVisible">
|
||||
<!--<div class="report-export">-->
|
||||
<el-card id="testOverview">
|
||||
<template v-slot:header >
|
||||
<slot name="header">
|
||||
<span class="title">{{$t('report.test_overview')}}</span>
|
||||
</slot>
|
||||
<span class="title">{{$t('report.test_overview')}}</span>
|
||||
</template>
|
||||
<ms-report-test-overview :report="report" ref="testOverview"/>
|
||||
</el-card>
|
||||
<el-card id="requestStatistics" title="'requestStatistics'">
|
||||
<template v-slot:header >
|
||||
<slot name="header">
|
||||
<span class="title">{{$t('report.test_request_statistics')}}</span>
|
||||
</slot>
|
||||
<span class="title">{{$t('report.test_request_statistics')}}</span>
|
||||
</template>
|
||||
<ms-report-request-statistics :report="report" ref="requestStatistics"/>
|
||||
</el-card>
|
||||
<el-card id="errorLog" title="'errorLog'">
|
||||
<template v-slot:header >
|
||||
<slot name="header">
|
||||
<span class="title">{{$t('report.test_error_log')}}</span>
|
||||
</slot>
|
||||
<span class="title">{{$t('report.test_error_log')}}</span>
|
||||
</template>
|
||||
<ms-report-error-log :report="report" ref="errorLog"/>
|
||||
</el-card>
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit f2d5a342c82e629f510550d5778d752bb73bf5e7
|
||||
Subproject commit 2c5f7e15858f51e836cffa911f8ab7511b3cc0d5
|
|
@ -94,7 +94,7 @@ export function saveLocalStorage(response) {
|
|||
|
||||
export function saveLicense(data) {
|
||||
// 保存License
|
||||
localStorage.setItem(LicenseKey, JSON.stringify(data));
|
||||
localStorage.setItem(LicenseKey, data);
|
||||
}
|
||||
|
||||
|
||||
|
@ -255,7 +255,7 @@ export function exportPdf(name, canvasList) {
|
|||
}
|
||||
}
|
||||
|
||||
pdf.save(name);
|
||||
pdf.save(name + '.pdf');
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue