refact: 解决冲突

This commit is contained in:
chenjianxing 2020-09-02 19:33:38 +08:00
commit 5b750fe55f
15 changed files with 856 additions and 213 deletions

View File

@ -20,7 +20,7 @@ MeterSphere 是一站式的开源企业级持续测试平台,涵盖测试跟
## UI 展示
![UI](https://metersphere.io/images/screenshot/ss07.png)
![UI](https://metersphere.io/images/screenshot/ss01.png)
## 在线体验
- 环境地址https://demo.metersphere.com/
@ -49,6 +49,9 @@ curl -sSL https://github.com/metersphere/metersphere/releases/latest/download/qu
- [完整文档](https://metersphere.io/docs/)
- [演示视频](http://video.fit2cloud.com/%E3%80%90%E6%BC%94%E7%A4%BA%E8%A7%86%E9%A2%91%E3%80%91202006%20MeterSphere%20v1.0%20%E5%8A%9F%E8%83%BD%E6%BC%94%E7%A4%BA.mp4)
## MeterSphere 企业版
[申请企业版使用](https://jinshuju.net/f/CzzAOe)
## 相关工具
- [Jenkins 插件](https://github.com/metersphere/jenkins-plugin)

View File

@ -0,0 +1,13 @@
package io.metersphere.base.domain;
import java.io.Serializable;
import lombok.Data;
@Data
public class TestPlanProject implements Serializable {
private String testPlanId;
private String projectId;
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,340 @@
package io.metersphere.base.domain;
import java.util.ArrayList;
import java.util.List;
public class TestPlanProjectExample {
protected String orderByClause;
protected boolean distinct;
protected List<Criteria> oredCriteria;
public TestPlanProjectExample() {
oredCriteria = new ArrayList<Criteria>();
}
public void setOrderByClause(String orderByClause) {
this.orderByClause = orderByClause;
}
public String getOrderByClause() {
return orderByClause;
}
public void setDistinct(boolean distinct) {
this.distinct = distinct;
}
public boolean isDistinct() {
return distinct;
}
public List<Criteria> getOredCriteria() {
return oredCriteria;
}
public void or(Criteria criteria) {
oredCriteria.add(criteria);
}
public Criteria or() {
Criteria criteria = createCriteriaInternal();
oredCriteria.add(criteria);
return criteria;
}
public Criteria createCriteria() {
Criteria criteria = createCriteriaInternal();
if (oredCriteria.size() == 0) {
oredCriteria.add(criteria);
}
return criteria;
}
protected Criteria createCriteriaInternal() {
Criteria criteria = new Criteria();
return criteria;
}
public void clear() {
oredCriteria.clear();
orderByClause = null;
distinct = false;
}
protected abstract static class GeneratedCriteria {
protected List<Criterion> criteria;
protected GeneratedCriteria() {
super();
criteria = new ArrayList<Criterion>();
}
public boolean isValid() {
return criteria.size() > 0;
}
public List<Criterion> getAllCriteria() {
return criteria;
}
public List<Criterion> getCriteria() {
return criteria;
}
protected void addCriterion(String condition) {
if (condition == null) {
throw new RuntimeException("Value for condition cannot be null");
}
criteria.add(new Criterion(condition));
}
protected void addCriterion(String condition, Object value, String property) {
if (value == null) {
throw new RuntimeException("Value for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value));
}
protected void addCriterion(String condition, Object value1, Object value2, String property) {
if (value1 == null || value2 == null) {
throw new RuntimeException("Between values for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value1, value2));
}
public Criteria andTestPlanIdIsNull() {
addCriterion("test_plan_id is null");
return (Criteria) this;
}
public Criteria andTestPlanIdIsNotNull() {
addCriterion("test_plan_id is not null");
return (Criteria) this;
}
public Criteria andTestPlanIdEqualTo(String value) {
addCriterion("test_plan_id =", value, "testPlanId");
return (Criteria) this;
}
public Criteria andTestPlanIdNotEqualTo(String value) {
addCriterion("test_plan_id <>", value, "testPlanId");
return (Criteria) this;
}
public Criteria andTestPlanIdGreaterThan(String value) {
addCriterion("test_plan_id >", value, "testPlanId");
return (Criteria) this;
}
public Criteria andTestPlanIdGreaterThanOrEqualTo(String value) {
addCriterion("test_plan_id >=", value, "testPlanId");
return (Criteria) this;
}
public Criteria andTestPlanIdLessThan(String value) {
addCriterion("test_plan_id <", value, "testPlanId");
return (Criteria) this;
}
public Criteria andTestPlanIdLessThanOrEqualTo(String value) {
addCriterion("test_plan_id <=", value, "testPlanId");
return (Criteria) this;
}
public Criteria andTestPlanIdLike(String value) {
addCriterion("test_plan_id like", value, "testPlanId");
return (Criteria) this;
}
public Criteria andTestPlanIdNotLike(String value) {
addCriterion("test_plan_id not like", value, "testPlanId");
return (Criteria) this;
}
public Criteria andTestPlanIdIn(List<String> values) {
addCriterion("test_plan_id in", values, "testPlanId");
return (Criteria) this;
}
public Criteria andTestPlanIdNotIn(List<String> values) {
addCriterion("test_plan_id not in", values, "testPlanId");
return (Criteria) this;
}
public Criteria andTestPlanIdBetween(String value1, String value2) {
addCriterion("test_plan_id between", value1, value2, "testPlanId");
return (Criteria) this;
}
public Criteria andTestPlanIdNotBetween(String value1, String value2) {
addCriterion("test_plan_id not between", value1, value2, "testPlanId");
return (Criteria) this;
}
public Criteria andProjectIdIsNull() {
addCriterion("project_id is null");
return (Criteria) this;
}
public Criteria andProjectIdIsNotNull() {
addCriterion("project_id is not null");
return (Criteria) this;
}
public Criteria andProjectIdEqualTo(String value) {
addCriterion("project_id =", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdNotEqualTo(String value) {
addCriterion("project_id <>", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdGreaterThan(String value) {
addCriterion("project_id >", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdGreaterThanOrEqualTo(String value) {
addCriterion("project_id >=", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdLessThan(String value) {
addCriterion("project_id <", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdLessThanOrEqualTo(String value) {
addCriterion("project_id <=", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdLike(String value) {
addCriterion("project_id like", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdNotLike(String value) {
addCriterion("project_id not like", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdIn(List<String> values) {
addCriterion("project_id in", values, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdNotIn(List<String> values) {
addCriterion("project_id not in", values, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdBetween(String value1, String value2) {
addCriterion("project_id between", value1, value2, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdNotBetween(String value1, String value2) {
addCriterion("project_id not between", value1, value2, "projectId");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {
protected Criteria() {
super();
}
}
public static class Criterion {
private String condition;
private Object value;
private Object secondValue;
private boolean noValue;
private boolean singleValue;
private boolean betweenValue;
private boolean listValue;
private String typeHandler;
public String getCondition() {
return condition;
}
public Object getValue() {
return value;
}
public Object getSecondValue() {
return secondValue;
}
public boolean isNoValue() {
return noValue;
}
public boolean isSingleValue() {
return singleValue;
}
public boolean isBetweenValue() {
return betweenValue;
}
public boolean isListValue() {
return listValue;
}
public String getTypeHandler() {
return typeHandler;
}
protected Criterion(String condition) {
super();
this.condition = condition;
this.typeHandler = null;
this.noValue = true;
}
protected Criterion(String condition, Object value, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.typeHandler = typeHandler;
if (value instanceof List<?>) {
this.listValue = true;
} else {
this.singleValue = true;
}
}
protected Criterion(String condition, Object value) {
this(condition, value, null);
}
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.secondValue = secondValue;
this.typeHandler = typeHandler;
this.betweenValue = true;
}
protected Criterion(String condition, Object value, Object secondValue) {
this(condition, value, secondValue, null);
}
}
}

View File

@ -0,0 +1,22 @@
package io.metersphere.base.mapper;
import io.metersphere.base.domain.TestPlanProject;
import io.metersphere.base.domain.TestPlanProjectExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;
public interface TestPlanProjectMapper {
long countByExample(TestPlanProjectExample example);
int deleteByExample(TestPlanProjectExample example);
int insert(TestPlanProject record);
int insertSelective(TestPlanProject record);
List<TestPlanProject> selectByExample(TestPlanProjectExample example);
int updateByExampleSelective(@Param("record") TestPlanProject record, @Param("example") TestPlanProjectExample example);
int updateByExample(@Param("record") TestPlanProject record, @Param("example") TestPlanProjectExample example);
}

View File

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.metersphere.base.mapper.TestPlanProjectMapper">
<resultMap id="BaseResultMap" type="io.metersphere.base.domain.TestPlanProject">
<result column="test_plan_id" jdbcType="VARCHAR" property="testPlanId" />
<result column="project_id" jdbcType="VARCHAR" property="projectId" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Update_By_Example_Where_Clause">
<where>
<foreach collection="example.oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List">
test_plan_id, project_id
</sql>
<select id="selectByExample" parameterType="io.metersphere.base.domain.TestPlanProjectExample" resultMap="BaseResultMap">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
from test_plan_project
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<delete id="deleteByExample" parameterType="io.metersphere.base.domain.TestPlanProjectExample">
delete from test_plan_project
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="io.metersphere.base.domain.TestPlanProject">
insert into test_plan_project (test_plan_id, project_id)
values (#{testPlanId,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestPlanProject">
insert into test_plan_project
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="testPlanId != null">
test_plan_id,
</if>
<if test="projectId != null">
project_id,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="testPlanId != null">
#{testPlanId,jdbcType=VARCHAR},
</if>
<if test="projectId != null">
#{projectId,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="io.metersphere.base.domain.TestPlanProjectExample" resultType="java.lang.Long">
select count(*) from test_plan_project
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</select>
<update id="updateByExampleSelective" parameterType="map">
update test_plan_project
<set>
<if test="record.testPlanId != null">
test_plan_id = #{record.testPlanId,jdbcType=VARCHAR},
</if>
<if test="record.projectId != null">
project_id = #{record.projectId,jdbcType=VARCHAR},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExample" parameterType="map">
update test_plan_project
set test_plan_id = #{record.testPlanId,jdbcType=VARCHAR},
project_id = #{record.projectId,jdbcType=VARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
</mapper>

View File

@ -11,6 +11,7 @@ import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.dto.LogDetailDTO;
import io.metersphere.dto.ReportDTO;
import io.metersphere.performance.base.*;
import io.metersphere.performance.controller.request.DeleteReportRequest;
import io.metersphere.performance.controller.request.ReportRequest;
import io.metersphere.performance.service.ReportService;
import org.apache.shiro.authz.annotation.Logical;
@ -113,4 +114,9 @@ public class PerformanceReportController {
public void downloadLog(@PathVariable String reportId, @PathVariable String resourceId, HttpServletResponse response) throws Exception {
reportService.downloadLog(response, reportId, resourceId);
}
@PostMapping("/batch/delete")
public void deleteReportBatch(@RequestBody DeleteReportRequest reportRequest) {
reportService.deleteReportBatch(reportRequest);
}
}

View File

@ -0,0 +1,13 @@
package io.metersphere.performance.controller.request;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class DeleteReportRequest {
private List<String> ids;
}

View File

@ -14,6 +14,7 @@ import io.metersphere.controller.request.OrderRequest;
import io.metersphere.dto.LogDetailDTO;
import io.metersphere.dto.ReportDTO;
import io.metersphere.performance.base.*;
import io.metersphere.performance.controller.request.DeleteReportRequest;
import io.metersphere.performance.controller.request.ReportRequest;
import io.metersphere.performance.engine.Engine;
import io.metersphere.performance.engine.EngineFactory;
@ -72,18 +73,22 @@ public class ReportService {
LogUtil.info("Delete report started, report ID: %s" + reportId);
final Engine engine = EngineFactory.createEngine(loadTest);
if (engine == null) {
MSException.throwException(String.format("Delete report fail. create engine failreport ID%s", reportId));
}
try {
final Engine engine = EngineFactory.createEngine(loadTest);
if (engine == null) {
MSException.throwException(String.format("Delete report fail. create engine failreport ID%s", reportId));
}
String reportStatus = loadTestReport.getStatus();
boolean isRunning = StringUtils.equals(reportStatus, PerformanceTestStatus.Running.name());
boolean isStarting = StringUtils.equals(reportStatus, PerformanceTestStatus.Starting.name());
boolean isError = StringUtils.equals(reportStatus, PerformanceTestStatus.Error.name());
if (isRunning || isStarting || isError) {
LogUtil.info("Start stop engine, report status: %s" + reportStatus);
stopEngine(loadTest, engine);
String reportStatus = loadTestReport.getStatus();
boolean isRunning = StringUtils.equals(reportStatus, PerformanceTestStatus.Running.name());
boolean isStarting = StringUtils.equals(reportStatus, PerformanceTestStatus.Starting.name());
boolean isError = StringUtils.equals(reportStatus, PerformanceTestStatus.Error.name());
if (isRunning || isStarting || isError) {
LogUtil.info("Start stop engine, report status: %s" + reportStatus);
stopEngine(loadTest, engine);
}
} catch (Exception e) {
LogUtil.error(e.getMessage(), e);
}
// delete load_test_report_result
@ -246,4 +251,9 @@ public class ReportService {
report.setStatus(status);
loadTestReportMapper.updateByPrimaryKeySelective(report);
}
public void deleteReportBatch(DeleteReportRequest reportRequest) {
List<String> ids = reportRequest.getIds();
ids.forEach(this::deleteReport);
}
}

View File

@ -0,0 +1,9 @@
create table if not exists test_plan_project
(
test_plan_id varchar(50) null,
project_id varchar(50) null,
constraint test_plan_project_pk
unique (test_plan_id, project_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
insert into test_plan_project(test_plan_id, project_id) select id test_plan_id, project_id project_id from test_plan;

View File

@ -1,104 +1,110 @@
<template>
<div class="schedule-config">
<div>
<div class="schedule-config">
<div>
<span class="cron-ico" @click="scheduleEdit">
<i class="el-icon-date" size="small"></i>
<span class="character">SCHEDULER</span>
</span>
<el-switch :disabled="!schedule.value || isReadOnly" v-model="schedule.enable" @change="scheduleChange"/>
<ms-schedule-edit :is-read-only="isReadOnly" :schedule="schedule" :save="save" :custom-validate="customValidate" ref="scheduleEdit"/>
<el-switch :disabled="!schedule.value || isReadOnly" v-model="schedule.enable" @change="scheduleChange"/>
<ms-schedule-edit :is-read-only="isReadOnly" :schedule="schedule" :save="save" :custom-validate="customValidate"
ref="scheduleEdit"/>
</div>
<div>
</div>
<div>
<span>
{{$t('schedule.next_execution_time')}}
<span :class="{'disable-character': !schedule.enable}" v-if="!schedule.enable">{{$t('schedule.not_set')}}</span>
{{ $t('schedule.next_execution_time') }}
<span :class="{'disable-character': !schedule.enable}"
v-if="!schedule.enable">{{ $t('schedule.not_set') }}</span>
<crontab-result v-if="schedule.enable" :enable-simple-mode="true" :ex="schedule.value" ref="crontabResult"/>
</span>
</div>
</div>
</div>
</template>
<script>
import MsScheduleEdit from "./MsScheduleEdit";
import CrontabResult from "../cron/CrontabResult";
import MsScheduleEdit from "./MsScheduleEdit";
import CrontabResult from "../cron/CrontabResult";
function defaultCustomValidate() {return {pass: true};}
function defaultCustomValidate() {
return {pass: true};
}
export default {
name: "MsScheduleConfig",
components: {CrontabResult, MsScheduleEdit},
data() {
export default {
name: "MsScheduleConfig",
components: {CrontabResult, MsScheduleEdit},
data() {
return {
recentList: [],
}
},
props: {
save: Function,
schedule: {},
checkOpen: {
type: Function,
default() {
return {
recentList: [],
}
},
props: {
save: Function,
schedule: {},
checkOpen: {
type: Function,
default() {
return {
checkOpen() {return true;}
}
checkOpen() {
return true;
}
},
customValidate: {
type: Function,
default: defaultCustomValidate
},
isReadOnly: {
type: Boolean,
default: false
}
},
methods: {
scheduleEdit() {
if (!this.checkOpen()) {
return;
}
this.$refs.scheduleEdit.open();
},
scheduleChange() {
this.$emit('scheduleChange');
},
flashResultList() {
this.$refs.crontabResult.expressionChange();
}
}
},
customValidate: {
type: Function,
default: defaultCustomValidate
},
isReadOnly: {
type: Boolean,
default: false
}
},
methods: {
scheduleEdit() {
if (!this.checkOpen()) {
return;
}
this.$refs.scheduleEdit.open();
},
scheduleChange() {
this.$emit('scheduleChange');
},
flashResultList() {
this.$refs.crontabResult.expressionChange();
}
}
}
</script>
<style scoped>
.schedule-config {
float: right;
width: 250px;
height: 15px;
line-height: 25px;
}
.schedule-config {
float: right;
width: 250px;
height: 15px;
line-height: 25px;
}
.el-icon-date {
font-size: 20px;
margin-left: 5px;
}
.el-icon-date {
font-size: 20px;
margin-left: 5px;
}
.character {
font-weight: bold;
margin: 0 5px;
}
.character {
font-weight: bold;
margin: 0 5px;
}
.disable-character {
color: #cccccc;
}
.disable-character {
color: #cccccc;
}
.el-switch {
margin: 0 5px;
}
.el-switch {
margin: 0 5px;
}
.cron-ico {
cursor: pointer;
}
.cron-ico {
cursor: pointer;
}
</style>

View File

@ -92,147 +92,147 @@
<script>
import Crontab from "../cron/Crontab";
import CrontabResult from "../cron/CrontabResult";
import {cronValidate} from "../../../../common/js/cron";
import {listenGoBack, removeGoBackListener} from "../../../../common/js/utils";
import Crontab from "../cron/Crontab";
import CrontabResult from "../cron/CrontabResult";
import {cronValidate} from "@/common/js/cron";
import {listenGoBack, removeGoBackListener} from "@/common/js/utils";
function defaultCustomValidate() {
return {pass: true};
}
function defaultCustomValidate() {
return {pass: true};
}
export default {
name: "MsScheduleEdit",
components: {CrontabResult, Crontab},
props: {
save: Function,
schedule: {},
customValidate: {
type: Function,
default: defaultCustomValidate
},
isReadOnly: {
type: Boolean,
default: false
}
export default {
name: "MsScheduleEdit",
components: {CrontabResult, Crontab},
props: {
save: Function,
schedule: {},
customValidate: {
type: Function,
default: defaultCustomValidate
},
watch: {
'schedule.value'() {
this.form.cronValue = this.schedule.value;
isReadOnly: {
type: Boolean,
default: false
}
},
watch: {
'schedule.value'() {
this.form.cronValue = this.schedule.value;
}
},
data() {
const validateCron = (rule, cronValue, callback) => {
let customValidate = this.customValidate(this.getIntervalTime());
if (!cronValue) {
callback(new Error(this.$t('commons.input_content')));
} else if (!cronValidate(cronValue)) {
callback(new Error(this.$t('schedule.cron_expression_format_error')));
}
},
data() {
const validateCron = (rule, cronValue, callback) => {
let customValidate = this.customValidate(this.getIntervalTime());
if (!cronValue) {
callback(new Error(this.$t('commons.input_content')));
} else if (!cronValidate(cronValue)) {
callback(new Error(this.$t('schedule.cron_expression_format_error')));
}
// else if(!this.intervalShortValidate()) {
// callback(new Error(this.$t('schedule.cron_expression_interval_short_error')));
// }
else if (!customValidate.pass) {
callback(new Error(customValidate.info));
} else {
callback();
}
};
return {
operation: true,
dialogVisible: false,
showCron: false,
form: {
cronValue: ""
},
tableData: [
{
event: '执行成功',
receiver: '',
email: '',
operation: 1
}, {
event: '执行成功',
receiver: '',
email: '',
operation: 2
}
],
email: "",
enable: true,
activeName: 'first',
rules: {
cronValue: [{required: true, validator: validateCron, trigger: 'blur'}],
}
// else if(!this.intervalShortValidate()) {
// callback(new Error(this.$t('schedule.cron_expression_interval_short_error')));
// }
else if (!customValidate.pass) {
callback(new Error(customValidate.info));
} else {
callback();
}
},
methods: {
handleClick() {
};
return {
operation: true,
dialogVisible: false,
showCron: false,
form: {
cronValue: ""
},
open() {
this.dialogVisible = true;
this.form.cronValue = this.schedule.value;
listenGoBack(this.close);
},
crontabFill(value, resultList) {
//
this.form.cronValue = value;
this.$refs.crontabResult.resultList = resultList;
this.$refs['from'].validate();
},
showCronDialog() {
this.showCron = true;
},
saveCron() {
this.$refs['from'].validate((valid) => {
if (valid) {
this.intervalShortValidate();
this.save(this.form.cronValue);
this.dialogVisible = false;
} else {
return false;
}
});
},
close() {
this.dialogVisible = false;
this.form.cronValue = '';
this.$refs['from'].resetFields();
if (!this.schedule.value) {
this.$refs.crontabResult.resultList = [];
tableData: [
{
event: '执行成功',
receiver: '',
email: '',
operation: 1
}, {
event: '执行成功',
receiver: '',
email: '',
operation: 2
}
removeGoBackListener(this.close);
},
intervalShortValidate() {
if (this.getIntervalTime() < 3 * 60 * 1000) {
// return false;
this.$info(this.$t('schedule.cron_expression_interval_short_error'));
}
return true;
},
resultListChange() {
this.$refs['from'].validate();
},
getIntervalTime() {
let resultList = this.$refs.crontabResult.resultList;
let time1 = new Date(resultList[0]);
let time2 = new Date(resultList[1]);
return time2 - time1;
],
email: "",
enable: true,
activeName: 'first',
rules: {
cronValue: [{required: true, validator: validateCron, trigger: 'blur'}],
}
}
},
methods: {
handleClick() {
},
open() {
this.dialogVisible = true;
this.form.cronValue = this.schedule.value;
listenGoBack(this.close);
},
crontabFill(value, resultList) {
//
this.form.cronValue = value;
this.$refs.crontabResult.resultList = resultList;
this.$refs['from'].validate();
},
showCronDialog() {
this.showCron = true;
},
saveCron() {
this.$refs['from'].validate((valid) => {
if (valid) {
this.intervalShortValidate();
this.save(this.form.cronValue);
this.dialogVisible = false;
} else {
return false;
}
});
},
close() {
this.dialogVisible = false;
this.form.cronValue = '';
this.$refs['from'].resetFields();
if (!this.schedule.value) {
this.$refs.crontabResult.resultList = [];
}
removeGoBackListener(this.close);
},
intervalShortValidate() {
if (this.getIntervalTime() < 3 * 60 * 1000) {
// return false;
this.$info(this.$t('schedule.cron_expression_interval_short_error'));
}
return true;
},
resultListChange() {
this.$refs['from'].validate();
},
getIntervalTime() {
let resultList = this.$refs.crontabResult.resultList;
let time1 = new Date(resultList[0]);
let time2 = new Date(resultList[1]);
return time2 - time1;
}
}
}
</script>
<style scoped>
.inp {
width: 50%;
margin-right: 20px;
}
.inp {
width: 50%;
margin-right: 20px;
}
.el-form-item {
margin-bottom: 10px;
}
.el-form-item {
margin-bottom: 10px;
}
</style>

View File

@ -9,9 +9,18 @@
</template>
<el-table border :data="tableData" class="adjust-table test-content"
@select-all="handleSelectAll"
@select="handleSelect"
@sort-change="sort"
@filter-change="filter"
>
<el-table-column
type="selection"/>
<el-table-column width="40" :resizable="false" align="center">
<template v-slot:default="scope">
<show-more-btn :is-show="scope.row.showMore" :buttons="buttons" :size="selectRows.size"/>
</template>
</el-table-column>
<el-table-column
prop="name"
:label="$t('commons.name')"
@ -89,13 +98,19 @@ import ReportTriggerModeItem from "../../common/tableItem/ReportTriggerModeItem"
import {REPORT_CONFIGS} from "../../common/components/search/search-components";
import MsTableHeader from "../../common/components/MsTableHeader";
import {LIST_CHANGE, PerformanceEvent} from "@/business/components/common/head/ListEvent";
import ShowMoreBtn from "../../track/case/components/ShowMoreBtn";
export default {
name: "PerformanceTestReport",
components: {
MsTableHeader,
ReportTriggerModeItem,
MsTableOperatorButton, MsPerformanceReportStatus, MsTablePagination, MsContainer, MsMainContainer
MsTableOperatorButton,
MsPerformanceReportStatus,
MsTablePagination,
MsContainer,
MsMainContainer,
ShowMoreBtn,
},
created: function () {
this.initTableData();
@ -128,6 +143,12 @@ export default {
{text: '定时任务', value: 'SCHEDULE'},
{text: 'API', value: 'API'}
],
buttons: [
{
name: this.$t('report.batch_delete'), handleClick: this.handleBatchDelete
}
],
selectRows: new Set(),
}
},
watch: {
@ -194,6 +215,60 @@ export default {
_filter(filters, this.condition);
this.initTableData();
},
handleSelect(selection, row) {
if (this.selectRows.has(row)) {
this.$set(row, "showMore", false);
this.selectRows.delete(row);
} else {
this.$set(row, "showMore", true);
this.selectRows.add(row);
}
let arr = Array.from(this.selectRows);
// 1
if (this.selectRows.size === 1) {
this.$set(arr[0], "showMore", false);
} else if (this.selectRows.size === 2) {
arr.forEach(row => {
this.$set(row, "showMore", true);
})
}
},
handleSelectAll(selection) {
if (selection.length > 0) {
if (selection.length === 1) {
this.selectRows.add(selection[0]);
} else {
this.tableData.forEach(item => {
this.$set(item, "showMore", true);
this.selectRows.add(item);
});
}
} else {
this.selectRows.clear();
this.tableData.forEach(row => {
this.$set(row, "showMore", false);
})
}
},
handleBatchDelete() {
this.$alert(this.$t('report.delete_batch_confirm') + "", '', {
confirmButtonText: this.$t('commons.confirm'),
callback: (action) => {
if (action === 'confirm') {
let ids = Array.from(this.selectRows).map(row => row.id);
this.result = this.$post('/performance/report/batch/delete', {ids: ids}, () => {
this.selectRows.clear();
this.$success(this.$t('commons.delete_success'));
this.search();
// 广 head
PerformanceEvent.$emit(LIST_CHANGE);
});
}
}
});
}
}
}
</script>

View File

@ -301,6 +301,8 @@ export default {
force_stop_btn: 'Terminating',
stop_btn: 'Graceful shutdown',
not_exist: "Test report does not exist",
batch_delete: "Delete reports in bulk",
delete_batch_confirm: 'Confirm batch delete report',
},
load_test: {
same_project_test: 'Only tests within the same project can be run',

View File

@ -301,6 +301,8 @@ export default {
force_stop_btn: '强制停止',
stop_btn: '停止',
not_exist: "测试报告不存在",
batch_delete: "批量删除报告",
delete_batch_confirm: '确认批量删除报告',
},
load_test: {
same_project_test: '只能运行同一项目内的测试',

View File

@ -300,6 +300,8 @@ export default {
force_stop_btn: '強制停止',
stop_btn: '停止',
not_exist: "測試報告不存在",
batch_delete: "批量刪除報告",
delete_batch_confirm: '確認批量刪除報告',
},
load_test: {
same_project_test: '只能運行同一項目內的測試',