Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
4102e2e667
|
@ -217,7 +217,7 @@ public class ApiAutomationService {
|
|||
ids.add(scenarioId);
|
||||
deleteApiScenarioReport(ids);
|
||||
|
||||
scheduleService.deleteByResourceId(scenarioId);
|
||||
scheduleService.deleteScheduleAndJobByResourceId(scenarioId,ScheduleGroup.API_SCENARIO_TEST.name());
|
||||
TestPlanApiScenarioExample example = new TestPlanApiScenarioExample();
|
||||
example.createCriteria().andApiScenarioIdEqualTo(scenarioId);
|
||||
List<TestPlanApiScenario> testPlanApiScenarioList = testPlanApiScenarioMapper.selectByExample(example);
|
||||
|
@ -282,6 +282,10 @@ public class ApiAutomationService {
|
|||
|
||||
public void removeToGc(List<String> apiIds) {
|
||||
extApiScenarioMapper.removeToGc(apiIds);
|
||||
//将这些场景的定时任务删除掉
|
||||
for (String id : apiIds) {
|
||||
scheduleService.deleteScheduleAndJobByResourceId(id,ScheduleGroup.API_SCENARIO_TEST.name());
|
||||
}
|
||||
}
|
||||
|
||||
public void reduction(List<SaveApiScenarioRequest> requests) {
|
||||
|
|
|
@ -33,5 +33,4 @@ public interface ScheduleMapper {
|
|||
int updateByPrimaryKeyWithBLOBs(Schedule record);
|
||||
|
||||
int updateByPrimaryKey(Schedule record);
|
||||
|
||||
}
|
|
@ -18,10 +18,7 @@ import io.metersphere.commons.utils.SessionUtils;
|
|||
import io.metersphere.controller.request.OrderRequest;
|
||||
import io.metersphere.controller.request.QueryScheduleRequest;
|
||||
import io.metersphere.dto.ScheduleDao;
|
||||
import io.metersphere.job.sechedule.ApiScenarioTestJob;
|
||||
import io.metersphere.job.sechedule.ApiTestJob;
|
||||
import io.metersphere.job.sechedule.ScheduleManager;
|
||||
import io.metersphere.job.sechedule.TestPlanTestJob;
|
||||
import io.metersphere.job.sechedule.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.quartz.JobKey;
|
||||
import org.quartz.SchedulerException;
|
||||
|
@ -98,6 +95,25 @@ public class ScheduleService {
|
|||
return scheduleMapper.deleteByExample(scheduleExample);
|
||||
}
|
||||
|
||||
public int deleteScheduleAndJobByResourceId(String resourceId,String group) {
|
||||
ScheduleExample scheduleExample = new ScheduleExample();
|
||||
scheduleExample.createCriteria().andResourceIdEqualTo(resourceId);
|
||||
removeJob(resourceId,group);
|
||||
return scheduleMapper.deleteByExample(scheduleExample);
|
||||
}
|
||||
|
||||
public void removeJob(String resourceId,String group) {
|
||||
if(StringUtils.equals(ScheduleGroup.API_SCENARIO_TEST.name(),group)){
|
||||
scheduleManager.removeJob(ApiScenarioTestJob.getJobKey(resourceId), ApiScenarioTestJob.getTriggerKey(resourceId));
|
||||
}else if(StringUtils.equals(ScheduleGroup.TEST_PLAN_TEST.name(),group)){
|
||||
scheduleManager.removeJob(TestPlanTestJob.getJobKey(resourceId), TestPlanTestJob.getTriggerKey(resourceId));
|
||||
}else if(StringUtils.equals(ScheduleGroup.SWAGGER_IMPORT.name(),group)){
|
||||
scheduleManager.removeJob(SwaggerUrlImportJob.getJobKey(resourceId), SwaggerUrlImportJob.getTriggerKey(resourceId));
|
||||
}else{
|
||||
scheduleManager.removeJob(ApiTestJob.getJobKey(resourceId), ApiTestJob.getTriggerKey(resourceId));
|
||||
}
|
||||
}
|
||||
|
||||
public List<Schedule> listSchedule() {
|
||||
ScheduleExample example = new ScheduleExample();
|
||||
return scheduleMapper.selectByExample(example);
|
||||
|
|
|
@ -28,6 +28,7 @@ import io.metersphere.dto.BaseSystemConfigDTO;
|
|||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.notice.sender.NoticeModel;
|
||||
import io.metersphere.notice.service.NoticeSendService;
|
||||
import io.metersphere.service.ScheduleService;
|
||||
import io.metersphere.service.SystemParameterService;
|
||||
import io.metersphere.track.Factory.ReportComponentFactory;
|
||||
import io.metersphere.track.domain.ReportComponent;
|
||||
|
@ -62,6 +63,8 @@ public class TestPlanService {
|
|||
@Resource
|
||||
ExtTestPlanMapper extTestPlanMapper;
|
||||
@Resource
|
||||
ScheduleService scheduleService;
|
||||
@Resource
|
||||
ExtTestPlanTestCaseMapper extTestPlanTestCaseMapper;
|
||||
@Resource
|
||||
TestCaseMapper testCaseMapper;
|
||||
|
@ -315,6 +318,10 @@ public class TestPlanService {
|
|||
testPlanProjectService.deleteTestPlanProjectByPlanId(planId);
|
||||
testPlanApiCaseService.deleteByPlanId(planId);
|
||||
testPlanScenarioCaseService.deleteByPlanId(planId);
|
||||
|
||||
//删除定时任务
|
||||
scheduleService.deleteScheduleAndJobByResourceId(planId,ScheduleGroup.TEST_PLAN_TEST.name());
|
||||
|
||||
int num = testPlanMapper.deleteByPrimaryKey(planId);
|
||||
List<String> relatedUsers = new ArrayList<>();
|
||||
AddTestPlanRequest testPlans = new AddTestPlanRequest();
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 214 KiB After Width: | Height: | Size: 169 KiB |
|
@ -286,8 +286,7 @@
|
|||
},
|
||||
response: {}
|
||||
}
|
||||
}
|
||||
,
|
||||
},
|
||||
created() {
|
||||
if (!this.currentScenario.apiScenarioModuleId) {
|
||||
this.currentScenario.apiScenarioModuleId = "";
|
||||
|
@ -857,6 +856,9 @@
|
|||
if (this.currentScenario.tags != undefined && !(this.currentScenario.tags instanceof Array)) {
|
||||
this.currentScenario.tags = JSON.parse(this.currentScenario.tags);
|
||||
}
|
||||
if (!this.currentScenario.variables) {
|
||||
this.currentScenario.variables = [];
|
||||
}
|
||||
if (this.currentScenario.id) {
|
||||
this.result = this.$get("/api/automation/getApiScenario/" + this.currentScenario.id, response => {
|
||||
if (response.data) {
|
||||
|
@ -1044,7 +1046,7 @@
|
|||
|
||||
.ms-tree >>> .el-icon-caret-right:before {
|
||||
content: '\e723';
|
||||
font-size: 18px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.ms-tree >>> .el-tree-node__expand-icon.is-leaf {
|
||||
|
@ -1058,6 +1060,6 @@
|
|||
.ms-tree >>> .el-tree-node__expand-icon.expanded.el-icon-caret-right:before {
|
||||
color: #7C3985;
|
||||
content: "\e722";
|
||||
font-size: 18px;
|
||||
font-size: 20px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -37,15 +37,17 @@
|
|||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header">
|
||||
<el-collapse-transition>
|
||||
<div v-if="data.active && showCollapse" :draggable="draggable">
|
||||
<fieldset :disabled="data.disabled" class="ms-fieldset">
|
||||
<el-divider></el-divider>
|
||||
<slot></slot>
|
||||
</fieldset>
|
||||
</div>
|
||||
</el-collapse-transition>
|
||||
</div>
|
||||
|
||||
<el-collapse-transition>
|
||||
<div v-if="data.active && showCollapse" :draggable="draggable">
|
||||
<fieldset :disabled="data.disabled" style="border: 0px">
|
||||
<el-divider></el-divider>
|
||||
<slot></slot>
|
||||
</fieldset>
|
||||
</div>
|
||||
</el-collapse-transition>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
|
@ -148,5 +150,12 @@
|
|||
.enable-switch {
|
||||
margin-right: 10px;
|
||||
}
|
||||
fieldset {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
min-width: 100%;
|
||||
min-inline-size: 0px;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -76,18 +76,20 @@
|
|||
</el-select>
|
||||
<el-input size="small" v-model="controller.whileController.value" :placeholder="$t('api_test.value')" v-if="!hasEmptyOperator" style="width: 20%;margin-left: 20px"/>
|
||||
<span class="ms-span ms-radio">{{$t('loop.timeout')}}</span>
|
||||
<el-input-number size="small" v-model="controller.whileController.timeout" :placeholder="$t('commons.millisecond')" :max="1000*10000000" :min="1" :step="1000"/>
|
||||
<el-input-number size="small" v-model="controller.whileController.timeout" :placeholder="$t('commons.millisecond')" :max="1000*10000000" :min="3000" :step="1000"/>
|
||||
<span class="ms-span ms-radio">ms</span>
|
||||
</div>
|
||||
|
||||
<p class="tip">{{$t('api_test.definition.request.res_param')}} </p>
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane :label="item.name" :name="item.name" v-for="(item,index) in requestResult.scenarios" :key="index">
|
||||
<div v-for="(result,i) in item.requestResults" :key="i" style="margin-bottom: 5px">
|
||||
<api-response-component :result="result"/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div>
|
||||
<el-tabs v-model="activeName" closable class="ms-tabs">
|
||||
<el-tab-pane :label="item.name" :name="item.name" v-for="(item,index) in requestResult.scenarios" :key="index">
|
||||
<div v-for="(result,i) in item.requestResults" :key="i" style="margin-bottom: 5px">
|
||||
<api-response-component :result="result"/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
</div>
|
||||
|
||||
</api-base-component>
|
||||
|
||||
|
@ -331,6 +333,11 @@
|
|||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.ms-tabs >>> .el-icon-close:before {
|
||||
content: "";
|
||||
|
||||
}
|
||||
|
||||
.icon.is-active {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,11 @@
|
|||
this.$refs.nameInput.focus();
|
||||
});
|
||||
},
|
||||
watch: {
|
||||
editData() {
|
||||
this.$refs.nameInput.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ import MsContainer from "../../../../common/components/MsContainer";
|
|||
import MsBottomContainer from "../BottomContainer";
|
||||
import ShowMoreBtn from "../../../../track/case/components/ShowMoreBtn";
|
||||
import MsBatchEdit from "../basis/BatchEdit";
|
||||
import {API_METHOD_COLOUR, CASE_PRIORITY, REQ_METHOD} from "../../model/JsonData";
|
||||
import {API_METHOD_COLOUR, CASE_PRIORITY, DUBBO_METHOD, REQ_METHOD, SQL_METHOD, TCP_METHOD} from "../../model/JsonData";
|
||||
|
||||
import {getBodyUploadFiles, getCurrentProjectID} from "@/common/js/utils";
|
||||
import ApiListContainer from "./ApiListContainer";
|
||||
|
@ -409,6 +409,15 @@ export default {
|
|||
// }
|
||||
},
|
||||
handleEditBatch() {
|
||||
if(this.currentProtocol =='HTTP'){
|
||||
this.valueArr.method = REQ_METHOD;
|
||||
}else if(this.currentProtocol =='TCP'){
|
||||
this.valueArr.method = TCP_METHOD;
|
||||
}else if(this.currentProtocol =='SQL'){
|
||||
this.valueArr.method = SQL_METHOD;
|
||||
}else if(this.currentProtocol =='DUBBO'){
|
||||
this.valueArr.method = DUBBO_METHOD;
|
||||
}
|
||||
this.$refs.batchEdit.open();
|
||||
},
|
||||
batchEdit(form) {
|
||||
|
|
|
@ -162,11 +162,10 @@
|
|||
import MsBottomContainer from "../BottomContainer";
|
||||
import ShowMoreBtn from "../../../../track/case/components/ShowMoreBtn";
|
||||
import MsBatchEdit from "../basis/BatchEdit";
|
||||
import {API_METHOD_COLOUR, API_STATUS, REQ_METHOD} from "../../model/JsonData";
|
||||
import {API_METHOD_COLOUR, API_STATUS, REQ_METHOD,TCP_METHOD,SQL_METHOD,DUBBO_METHOD} from "../../model/JsonData";
|
||||
import {_filter, _sort, getCurrentProjectID} from "@/common/js/utils";
|
||||
import {WORKSPACE_ID} from '@/common/js/constants';
|
||||
import ApiListContainer from "./ApiListContainer";
|
||||
// import MsTableSelectAll from "../../../../common/components/table/MsTableSelectAll";
|
||||
import MsTableHeaderSelectPopover from "@/business/components/common/components/table/MsTableHeaderSelectPopover";
|
||||
import ApiStatus from "@/business/components/api/definition/components/list/ApiStatus";
|
||||
import MsTableAdvSearchBar from "@/business/components/common/components/search/MsTableAdvSearchBar";
|
||||
|
@ -513,6 +512,15 @@
|
|||
}
|
||||
},
|
||||
handleEditBatch() {
|
||||
if(this.currentProtocol =='HTTP'){
|
||||
this.valueArr.method = REQ_METHOD;
|
||||
}else if(this.currentProtocol =='TCP'){
|
||||
this.valueArr.method = TCP_METHOD;
|
||||
}else if(this.currentProtocol =='SQL'){
|
||||
this.valueArr.method = SQL_METHOD;
|
||||
}else if(this.currentProtocol =='DUBBO'){
|
||||
this.valueArr.method = DUBBO_METHOD;
|
||||
}
|
||||
this.$refs.batchEdit.open();
|
||||
},
|
||||
batchEdit(form) {
|
||||
|
|
|
@ -235,15 +235,22 @@
|
|||
this.$refs.environmentConfig.open(getCurrentProjectID());
|
||||
},
|
||||
initDataSource() {
|
||||
let flag = false;
|
||||
for (let i in this.environments) {
|
||||
if (this.environments[i].id === this.request.environmentId) {
|
||||
this.databaseConfigsOptions = [];
|
||||
this.environments[i].config.databaseConfigs.forEach(item => {
|
||||
if (item.id === this.request.dataSourceId) {
|
||||
flag = true;
|
||||
}
|
||||
this.databaseConfigsOptions.push(item);
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!flag) {
|
||||
this.request.dataSourceId = undefined;
|
||||
}
|
||||
},
|
||||
setDataSource() {
|
||||
for (let item of this.databaseConfigsOptions) {
|
||||
|
|
|
@ -44,6 +44,15 @@ export const REQ_METHOD = [
|
|||
{id: 'HEAD', label: 'HEAD'},
|
||||
{id: 'CONNECT', label: 'CONNECT'}
|
||||
]
|
||||
export const TCP_METHOD = [
|
||||
{id: 'TCP', label: 'TCP'}
|
||||
]
|
||||
export const SQL_METHOD = [
|
||||
{id: 'SQL', label: 'SQL'}
|
||||
]
|
||||
export const DUBBO_METHOD = [
|
||||
{id: 'dubbo://', label: 'dubbo://'},
|
||||
]
|
||||
|
||||
export const CASE_PRIORITY = [
|
||||
{id: 'P0', label: 'P0'},
|
||||
|
|
|
@ -89,9 +89,6 @@
|
|||
selectRows: new Set()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.search();
|
||||
},
|
||||
watch: {
|
||||
selectNodeIds() {
|
||||
this.search();
|
||||
|
@ -102,6 +99,9 @@
|
|||
},
|
||||
methods: {
|
||||
search() {
|
||||
if (!this.projectId) {
|
||||
return;
|
||||
}
|
||||
this.selectRows = new Set();
|
||||
this.loading = true;
|
||||
|
||||
|
|
|
@ -75,6 +75,9 @@
|
|||
methods: {
|
||||
open() {
|
||||
this.$refs.baseRelevance.open();
|
||||
if (this.$refs.apiScenarioList) {
|
||||
this.$refs.apiScenarioList.search();
|
||||
}
|
||||
},
|
||||
setProject(projectId) {
|
||||
this.projectId = projectId;
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<div class="divider"/>
|
||||
|
||||
<el-col :span="12">
|
||||
<img :src="'/display/file/loginImage'" style="height: 568px; width: 100%">
|
||||
<img class="login-image" :src="'/display/file/loginImage'">
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
|
@ -66,15 +66,6 @@ const auth = requireComponent.keys().length > 0 ? requireComponent("./auth/Auth.
|
|||
export default {
|
||||
name: "Login",
|
||||
data() {
|
||||
/*let validateEmail = (rule, value, callback) => {
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
let EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
if (!EMAIL_REGEX.test(value)) {
|
||||
callback(new Error('邮箱格式不正确'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};*/
|
||||
return {
|
||||
result: {},
|
||||
form: {
|
||||
|
@ -192,66 +183,51 @@ export default {
|
|||
|
||||
<style scoped>
|
||||
.container {
|
||||
min-width: 800px;
|
||||
max-width: 1440px;
|
||||
height: 568px;
|
||||
margin: calc((100vh - 568px) / 2) auto 0;
|
||||
width: 1440px;
|
||||
height: 810px;
|
||||
margin: calc((100vh - 810px) / 2) auto 0;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
.image {
|
||||
background: url(../assets/info.png);
|
||||
.el-col:nth-child(3) {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.login-logo {
|
||||
background: url(../assets/logo-dark-MeterSphere.svg);
|
||||
}
|
||||
|
||||
.logo-header {
|
||||
background: url(../assets/logo-light-MeterSphere.svg);
|
||||
}
|
||||
|
||||
.el-col {
|
||||
height: 568px;
|
||||
.title img {
|
||||
width: 293px;
|
||||
margin-top: 165px;
|
||||
}
|
||||
|
||||
.title-img {
|
||||
font-size: 32px;
|
||||
letter-spacing: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.login-image {
|
||||
height: 365px;
|
||||
width: 567px;
|
||||
margin: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.welcome {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 50px;
|
||||
font-size: 18px;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 75px;
|
||||
font-size: 14px;
|
||||
color: #843697;
|
||||
line-height: 18px;
|
||||
line-height: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.form {
|
||||
padding: 0 40px;
|
||||
}
|
||||
|
||||
.title {
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.content {
|
||||
height: 50%;
|
||||
padding: 0px 90px;
|
||||
margin-top: -20px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-top: 40px;
|
||||
padding: 0 40px;
|
||||
.form,.btn {
|
||||
padding: 0;
|
||||
width: 443px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.btn > .submit {
|
||||
width: 100%;
|
||||
border-radius: 50px;
|
||||
border-radius: 70px;
|
||||
border-color: #8B479B;
|
||||
background-color: #8B479B;
|
||||
}
|
||||
|
@ -266,11 +242,8 @@ export default {
|
|||
background-color: rgba(139, 71, 155, 0.8);
|
||||
}
|
||||
|
||||
.msg {
|
||||
margin-top: 10px;
|
||||
padding: 0 40px;
|
||||
color: red;
|
||||
text-align: center;
|
||||
.el-form-item:first-child {
|
||||
margin-top: 60px;
|
||||
}
|
||||
|
||||
/deep/ .el-radio__input.is-checked .el-radio__inner {
|
||||
|
@ -284,23 +257,25 @@ export default {
|
|||
}
|
||||
|
||||
/deep/ .el-input__inner {
|
||||
border-radius: 70px !important;
|
||||
background: #f6f3f8 !important;
|
||||
border-color: #f6f3f8;
|
||||
border-radius: 50px !important;
|
||||
border-color: #f6f3f8 !important;
|
||||
/*谷歌浏览器默认填充的颜色无法替换,使用下列样式填充*/
|
||||
box-shadow: inset 0 0 0 1000px #f6f3f8 !important;
|
||||
}
|
||||
|
||||
.el-input,.el-button {
|
||||
width: 443px;
|
||||
}
|
||||
|
||||
/deep/ .el-input__inner:focus {
|
||||
border: 1px solid #783887;
|
||||
border: 1px solid #783887 !important;
|
||||
}
|
||||
|
||||
.divider {
|
||||
border: 1px solid #f6f3f8;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.title img {
|
||||
height: 60px;
|
||||
margin-top: 120px;
|
||||
height: 480px;
|
||||
margin: 165px 0px;
|
||||
}
|
||||
|
||||
.welcome span:first-child {
|
||||
|
@ -314,7 +289,7 @@ export default {
|
|||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Neue Haas Grotesk Text Pro", "Arial Nova", "Segoe UI", "Helvetica Neue", ".PingFang SC", "PingFang SC", "Source Han Sans SC", "Noto Sans CJK SC", "Source Han Sans CN", "Noto Sans SC", "Source Han Sans TC", "Noto Sans CJK TC", "Hiragino Sans GB", sans-serif;
|
||||
font-size: 14px;
|
||||
background-color: #F5F5F5;
|
||||
/*background-color: #F5F5F5;*/
|
||||
line-height: 26px;
|
||||
color: #2B415C;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
|
|
|
@ -4,6 +4,10 @@ import 'element-ui/lib/theme-chalk/index.css';
|
|||
import Login from "./Login.vue";
|
||||
import Ajax from "../common/js/ajax";
|
||||
import i18n from "../i18n/i18n";
|
||||
// 引用静态资源,去掉打包将缺失图片
|
||||
import infoImg from "../assets/info.png";
|
||||
import loginLogo from "../assets/logo-dark-MeterSphere.svg";
|
||||
import logoHeader from "../assets/logo-light-MeterSphere.svg";
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
|
||||
|
|
Loading…
Reference in New Issue