Merge branch 'master' of https://github.com/metersphere/metersphere
This commit is contained in:
commit
6ec08c0ec5
|
@ -12,6 +12,7 @@ public class KeyValue {
|
||||||
private String type;
|
private String type;
|
||||||
private List<BodyFile> files;
|
private List<BodyFile> files;
|
||||||
private String description;
|
private String description;
|
||||||
|
private String contentType;
|
||||||
private boolean enable;
|
private boolean enable;
|
||||||
|
|
||||||
public KeyValue() {
|
public KeyValue() {
|
||||||
|
|
|
@ -3,11 +3,11 @@ package io.metersphere.api.jmeter;
|
||||||
import io.metersphere.api.service.APIReportService;
|
import io.metersphere.api.service.APIReportService;
|
||||||
import io.metersphere.api.service.APITestService;
|
import io.metersphere.api.service.APITestService;
|
||||||
import io.metersphere.base.domain.ApiTestReport;
|
import io.metersphere.base.domain.ApiTestReport;
|
||||||
import io.metersphere.base.domain.Notice;
|
|
||||||
import io.metersphere.commons.constants.APITestStatus;
|
import io.metersphere.commons.constants.APITestStatus;
|
||||||
import io.metersphere.commons.constants.ApiRunMode;
|
import io.metersphere.commons.constants.ApiRunMode;
|
||||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
import io.metersphere.notice.domain.NoticeDetail;
|
||||||
import io.metersphere.notice.service.MailService;
|
import io.metersphere.notice.service.MailService;
|
||||||
import io.metersphere.notice.service.NoticeService;
|
import io.metersphere.notice.service.NoticeService;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
@ -16,7 +16,6 @@ import org.apache.jmeter.samplers.SampleResult;
|
||||||
import org.apache.jmeter.visualizers.backend.AbstractBackendListenerClient;
|
import org.apache.jmeter.visualizers.backend.AbstractBackendListenerClient;
|
||||||
import org.apache.jmeter.visualizers.backend.BackendListenerContext;
|
import org.apache.jmeter.visualizers.backend.BackendListenerContext;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@ -120,17 +119,17 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
|
||||||
queue.clear();
|
queue.clear();
|
||||||
super.teardownTest(context);
|
super.teardownTest(context);
|
||||||
NoticeService noticeService = CommonBeanFactory.getBean(NoticeService.class);
|
NoticeService noticeService = CommonBeanFactory.getBean(NoticeService.class);
|
||||||
List<Notice> notice = null;
|
List<NoticeDetail> notice = null;
|
||||||
try {
|
try {
|
||||||
notice = noticeService.queryNotice(testResult.getTestId());
|
notice = noticeService.queryNotice(testResult.getTestId());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
LogUtil.error(e);
|
||||||
}
|
}
|
||||||
MailService mailService = CommonBeanFactory.getBean(MailService.class);
|
MailService mailService = CommonBeanFactory.getBean(MailService.class);
|
||||||
try {
|
try {
|
||||||
mailService.sendHtml(report.getId(), notice, report.getStatus(), "api");
|
mailService.sendHtml(report.getId(), notice, report.getStatus(), "api");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
LogUtil.error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package io.metersphere.base.domain;
|
package io.metersphere.base.domain;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class Notice implements Serializable {
|
public class Notice implements Serializable {
|
||||||
private String event;
|
private String event;
|
||||||
|
@ -15,9 +16,5 @@ public class Notice implements Serializable {
|
||||||
|
|
||||||
private String enable;
|
private String enable;
|
||||||
|
|
||||||
private String[] names;
|
|
||||||
|
|
||||||
private String[] emails;
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
}
|
}
|
|
@ -25,6 +25,14 @@ public class TestPlan implements Serializable {
|
||||||
|
|
||||||
private String executorMatchRule;
|
private String executorMatchRule;
|
||||||
|
|
||||||
|
private Long plannedStartTime;
|
||||||
|
|
||||||
|
private Long plannedEndTime;
|
||||||
|
|
||||||
|
private Long actualStartTime;
|
||||||
|
|
||||||
|
private Long actualEndTime;
|
||||||
|
|
||||||
private Long createTime;
|
private Long createTime;
|
||||||
|
|
||||||
private Long updateTime;
|
private Long updateTime;
|
||||||
|
|
|
@ -12,6 +12,10 @@
|
||||||
<result column="principal" jdbcType="VARCHAR" property="principal" />
|
<result column="principal" jdbcType="VARCHAR" property="principal" />
|
||||||
<result column="test_case_match_rule" jdbcType="VARCHAR" property="testCaseMatchRule" />
|
<result column="test_case_match_rule" jdbcType="VARCHAR" property="testCaseMatchRule" />
|
||||||
<result column="executor_match_rule" jdbcType="VARCHAR" property="executorMatchRule" />
|
<result column="executor_match_rule" jdbcType="VARCHAR" property="executorMatchRule" />
|
||||||
|
<result column="planned_start_time" jdbcType="BIGINT" property="plannedStartTime" />
|
||||||
|
<result column="planned_end_time" jdbcType="BIGINT" property="plannedEndTime" />
|
||||||
|
<result column="actual_start_time" jdbcType="BIGINT" property="actualStartTime" />
|
||||||
|
<result column="actual_end_time" jdbcType="BIGINT" property="actualEndTime" />
|
||||||
<result column="create_time" jdbcType="BIGINT" property="createTime" />
|
<result column="create_time" jdbcType="BIGINT" property="createTime" />
|
||||||
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
|
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
@ -78,7 +82,7 @@
|
||||||
</sql>
|
</sql>
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
id, workspace_id, report_id, `name`, description, `status`, stage, principal, test_case_match_rule,
|
id, workspace_id, report_id, `name`, description, `status`, stage, principal, test_case_match_rule,
|
||||||
executor_match_rule, create_time, update_time
|
executor_match_rule, planned_start_time, planned_end_time, actual_start_time, actual_end_time, create_time, update_time
|
||||||
</sql>
|
</sql>
|
||||||
<sql id="Blob_Column_List">
|
<sql id="Blob_Column_List">
|
||||||
tags
|
tags
|
||||||
|
@ -114,7 +118,7 @@
|
||||||
</if>
|
</if>
|
||||||
</select>
|
</select>
|
||||||
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="ResultMapWithBLOBs">
|
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="ResultMapWithBLOBs">
|
||||||
select
|
select
|
||||||
<include refid="Base_Column_List" />
|
<include refid="Base_Column_List" />
|
||||||
,
|
,
|
||||||
<include refid="Blob_Column_List" />
|
<include refid="Blob_Column_List" />
|
||||||
|
@ -132,16 +136,16 @@
|
||||||
</if>
|
</if>
|
||||||
</delete>
|
</delete>
|
||||||
<insert id="insert" parameterType="io.metersphere.base.domain.TestPlan">
|
<insert id="insert" parameterType="io.metersphere.base.domain.TestPlan">
|
||||||
insert into test_plan (id, workspace_id, report_id,
|
insert into test_plan (id, workspace_id, report_id,
|
||||||
`name`, description, `status`,
|
`name`, description, `status`,
|
||||||
stage, principal, test_case_match_rule,
|
stage, principal, test_case_match_rule,
|
||||||
executor_match_rule, create_time, update_time,
|
executor_match_rule, planned_start_time, planned_end_time, create_time,
|
||||||
tags)
|
update_time, tags)
|
||||||
values (#{id,jdbcType=VARCHAR}, #{workspaceId,jdbcType=VARCHAR}, #{reportId,jdbcType=VARCHAR},
|
values (#{id,jdbcType=VARCHAR}, #{workspaceId,jdbcType=VARCHAR}, #{reportId,jdbcType=VARCHAR},
|
||||||
#{name,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR},
|
#{name,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR},
|
||||||
#{stage,jdbcType=VARCHAR}, #{principal,jdbcType=VARCHAR}, #{testCaseMatchRule,jdbcType=VARCHAR},
|
#{stage,jdbcType=VARCHAR}, #{principal,jdbcType=VARCHAR}, #{testCaseMatchRule,jdbcType=VARCHAR},
|
||||||
#{executorMatchRule,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
|
#{executorMatchRule,jdbcType=VARCHAR}, #{plannedStartTime,jdbcType=BIGINT}, #{plannedEndTime,jdbcType=BIGINT},
|
||||||
#{tags,jdbcType=LONGVARCHAR})
|
#{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{tags,jdbcType=LONGVARCHAR})
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestPlan">
|
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestPlan">
|
||||||
insert into test_plan
|
insert into test_plan
|
||||||
|
@ -176,6 +180,12 @@
|
||||||
<if test="executorMatchRule != null">
|
<if test="executorMatchRule != null">
|
||||||
executor_match_rule,
|
executor_match_rule,
|
||||||
</if>
|
</if>
|
||||||
|
<if test="plannedStartTime != null">
|
||||||
|
planned_start_time,
|
||||||
|
</if>
|
||||||
|
<if test="plannedEndTime != null">
|
||||||
|
planned_end_time,
|
||||||
|
</if>
|
||||||
<if test="createTime != null">
|
<if test="createTime != null">
|
||||||
create_time,
|
create_time,
|
||||||
</if>
|
</if>
|
||||||
|
@ -217,6 +227,12 @@
|
||||||
<if test="executorMatchRule != null">
|
<if test="executorMatchRule != null">
|
||||||
#{executorMatchRule,jdbcType=VARCHAR},
|
#{executorMatchRule,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="plannedStartTime != null">
|
||||||
|
#{plannedStartTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="plannedEndTime != null">
|
||||||
|
#{plannedEndTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
<if test="createTime != null">
|
<if test="createTime != null">
|
||||||
#{createTime,jdbcType=BIGINT},
|
#{createTime,jdbcType=BIGINT},
|
||||||
</if>
|
</if>
|
||||||
|
@ -267,6 +283,18 @@
|
||||||
<if test="record.executorMatchRule != null">
|
<if test="record.executorMatchRule != null">
|
||||||
executor_match_rule = #{record.executorMatchRule,jdbcType=VARCHAR},
|
executor_match_rule = #{record.executorMatchRule,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="record.plannedStartTime != null">
|
||||||
|
planned_start_time = #{record.plannedStartTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="record.plannedEndTime != null">
|
||||||
|
planned_end_time = #{record.plannedEndTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="record.actualStartTime != null">
|
||||||
|
actual_start_time = #{record.actualStartTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="record.actualEndTime != null">
|
||||||
|
actual_end_time = #{record.actualEndTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
<if test="record.createTime != null">
|
<if test="record.createTime != null">
|
||||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||||
</if>
|
</if>
|
||||||
|
@ -284,18 +312,22 @@
|
||||||
<update id="updateByExampleWithBLOBs" parameterType="map">
|
<update id="updateByExampleWithBLOBs" parameterType="map">
|
||||||
update test_plan
|
update test_plan
|
||||||
set id = #{record.id,jdbcType=VARCHAR},
|
set id = #{record.id,jdbcType=VARCHAR},
|
||||||
workspace_id = #{record.workspaceId,jdbcType=VARCHAR},
|
workspace_id = #{record.workspaceId,jdbcType=VARCHAR},
|
||||||
report_id = #{record.reportId,jdbcType=VARCHAR},
|
report_id = #{record.reportId,jdbcType=VARCHAR},
|
||||||
`name` = #{record.name,jdbcType=VARCHAR},
|
`name` = #{record.name,jdbcType=VARCHAR},
|
||||||
description = #{record.description,jdbcType=VARCHAR},
|
description = #{record.description,jdbcType=VARCHAR},
|
||||||
`status` = #{record.status,jdbcType=VARCHAR},
|
`status` = #{record.status,jdbcType=VARCHAR},
|
||||||
stage = #{record.stage,jdbcType=VARCHAR},
|
stage = #{record.stage,jdbcType=VARCHAR},
|
||||||
principal = #{record.principal,jdbcType=VARCHAR},
|
principal = #{record.principal,jdbcType=VARCHAR},
|
||||||
test_case_match_rule = #{record.testCaseMatchRule,jdbcType=VARCHAR},
|
test_case_match_rule = #{record.testCaseMatchRule,jdbcType=VARCHAR},
|
||||||
executor_match_rule = #{record.executorMatchRule,jdbcType=VARCHAR},
|
executor_match_rule = #{record.executorMatchRule,jdbcType=VARCHAR},
|
||||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
planned_start_time = #{record.plannedStartTime,jdbcType=BIGINT},
|
||||||
update_time = #{record.updateTime,jdbcType=BIGINT},
|
planned_end_time = #{record.plannedEndTime,jdbcType=BIGINT},
|
||||||
tags = #{record.tags,jdbcType=LONGVARCHAR}
|
actual_start_time = #{record.actualStartTime,jdbcType=BIGINT},
|
||||||
|
actual_end_time = #{record.actualEndTime,jdbcType=BIGINT},
|
||||||
|
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||||
|
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||||
|
tags = #{record.tags,jdbcType=LONGVARCHAR}
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
<include refid="Update_By_Example_Where_Clause" />
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
</if>
|
</if>
|
||||||
|
@ -303,17 +335,21 @@
|
||||||
<update id="updateByExample" parameterType="map">
|
<update id="updateByExample" parameterType="map">
|
||||||
update test_plan
|
update test_plan
|
||||||
set id = #{record.id,jdbcType=VARCHAR},
|
set id = #{record.id,jdbcType=VARCHAR},
|
||||||
workspace_id = #{record.workspaceId,jdbcType=VARCHAR},
|
workspace_id = #{record.workspaceId,jdbcType=VARCHAR},
|
||||||
report_id = #{record.reportId,jdbcType=VARCHAR},
|
report_id = #{record.reportId,jdbcType=VARCHAR},
|
||||||
`name` = #{record.name,jdbcType=VARCHAR},
|
`name` = #{record.name,jdbcType=VARCHAR},
|
||||||
description = #{record.description,jdbcType=VARCHAR},
|
description = #{record.description,jdbcType=VARCHAR},
|
||||||
`status` = #{record.status,jdbcType=VARCHAR},
|
`status` = #{record.status,jdbcType=VARCHAR},
|
||||||
stage = #{record.stage,jdbcType=VARCHAR},
|
stage = #{record.stage,jdbcType=VARCHAR},
|
||||||
principal = #{record.principal,jdbcType=VARCHAR},
|
principal = #{record.principal,jdbcType=VARCHAR},
|
||||||
test_case_match_rule = #{record.testCaseMatchRule,jdbcType=VARCHAR},
|
test_case_match_rule = #{record.testCaseMatchRule,jdbcType=VARCHAR},
|
||||||
executor_match_rule = #{record.executorMatchRule,jdbcType=VARCHAR},
|
executor_match_rule = #{record.executorMatchRule,jdbcType=VARCHAR},
|
||||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
planned_start_time = #{record.plannedStartTime,jdbcType=BIGINT},
|
||||||
update_time = #{record.updateTime,jdbcType=BIGINT}
|
planned_end_time = #{record.plannedEndTime,jdbcType=BIGINT},
|
||||||
|
actual_start_time = #{record.actualStartTime,jdbcType=BIGINT},
|
||||||
|
actual_end_time = #{record.actualEndTime,jdbcType=BIGINT},
|
||||||
|
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||||
|
update_time = #{record.updateTime,jdbcType=BIGINT}
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
<include refid="Update_By_Example_Where_Clause" />
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
</if>
|
</if>
|
||||||
|
@ -348,6 +384,18 @@
|
||||||
<if test="executorMatchRule != null">
|
<if test="executorMatchRule != null">
|
||||||
executor_match_rule = #{executorMatchRule,jdbcType=VARCHAR},
|
executor_match_rule = #{executorMatchRule,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="plannedStartTime != null">
|
||||||
|
planned_start_time = #{plannedStartTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="plannedEndTime != null">
|
||||||
|
planned_end_time = #{plannedEndTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="actualStartTime != null">
|
||||||
|
actual_start_time = #{actualStartTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="actualEndTime != null">
|
||||||
|
actual_end_time = #{actualEndTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
<if test="createTime != null">
|
<if test="createTime != null">
|
||||||
create_time = #{createTime,jdbcType=BIGINT},
|
create_time = #{createTime,jdbcType=BIGINT},
|
||||||
</if>
|
</if>
|
||||||
|
@ -371,6 +419,10 @@
|
||||||
principal = #{principal,jdbcType=VARCHAR},
|
principal = #{principal,jdbcType=VARCHAR},
|
||||||
test_case_match_rule = #{testCaseMatchRule,jdbcType=VARCHAR},
|
test_case_match_rule = #{testCaseMatchRule,jdbcType=VARCHAR},
|
||||||
executor_match_rule = #{executorMatchRule,jdbcType=VARCHAR},
|
executor_match_rule = #{executorMatchRule,jdbcType=VARCHAR},
|
||||||
|
planned_start_time = #{plannedStartTime,jdbcType=BIGINT},
|
||||||
|
planned_end_time = #{plannedEndTime,jdbcType=BIGINT},
|
||||||
|
actual_start_time = #{actualStartTime,jdbcType=BIGINT},
|
||||||
|
actual_end_time = #{actualEndTime,jdbcType=BIGINT},
|
||||||
create_time = #{createTime,jdbcType=BIGINT},
|
create_time = #{createTime,jdbcType=BIGINT},
|
||||||
update_time = #{updateTime,jdbcType=BIGINT},
|
update_time = #{updateTime,jdbcType=BIGINT},
|
||||||
tags = #{tags,jdbcType=LONGVARCHAR}
|
tags = #{tags,jdbcType=LONGVARCHAR}
|
||||||
|
@ -387,6 +439,10 @@
|
||||||
principal = #{principal,jdbcType=VARCHAR},
|
principal = #{principal,jdbcType=VARCHAR},
|
||||||
test_case_match_rule = #{testCaseMatchRule,jdbcType=VARCHAR},
|
test_case_match_rule = #{testCaseMatchRule,jdbcType=VARCHAR},
|
||||||
executor_match_rule = #{executorMatchRule,jdbcType=VARCHAR},
|
executor_match_rule = #{executorMatchRule,jdbcType=VARCHAR},
|
||||||
|
planned_start_time = #{plannedStartTime,jdbcType=BIGINT},
|
||||||
|
planned_end_time = #{plannedEndTime,jdbcType=BIGINT},
|
||||||
|
actual_start_time = #{actualStartTime,jdbcType=BIGINT},
|
||||||
|
actual_end_time = #{actualEndTime,jdbcType=BIGINT},
|
||||||
create_time = #{createTime,jdbcType=BIGINT},
|
create_time = #{createTime,jdbcType=BIGINT},
|
||||||
update_time = #{updateTime,jdbcType=BIGINT}
|
update_time = #{updateTime,jdbcType=BIGINT}
|
||||||
where id = #{id,jdbcType=VARCHAR}
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
|
|
|
@ -29,6 +29,7 @@ public interface ParamConstants {
|
||||||
|
|
||||||
enum Classify implements ParamConstants {
|
enum Classify implements ParamConstants {
|
||||||
MAIL("smtp"),
|
MAIL("smtp"),
|
||||||
|
BASE("base"),
|
||||||
LDAP("ldap"),
|
LDAP("ldap"),
|
||||||
REGISTRY("registry");
|
REGISTRY("registry");
|
||||||
|
|
||||||
|
@ -114,6 +115,21 @@ public interface ParamConstants {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum BASE implements ParamConstants {
|
||||||
|
URL("base.url");
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
private BASE(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum LDAP implements ParamConstants {
|
enum LDAP implements ParamConstants {
|
||||||
URL("ldap.url"),
|
URL("ldap.url"),
|
||||||
DN("ldap.dn"),
|
DN("ldap.dn"),
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.controller;
|
||||||
import io.metersphere.base.domain.SystemParameter;
|
import io.metersphere.base.domain.SystemParameter;
|
||||||
import io.metersphere.commons.constants.ParamConstants;
|
import io.metersphere.commons.constants.ParamConstants;
|
||||||
import io.metersphere.commons.constants.RoleConstants;
|
import io.metersphere.commons.constants.RoleConstants;
|
||||||
|
import io.metersphere.dto.BaseSystemConfigDTO;
|
||||||
import io.metersphere.ldap.domain.LdapInfo;
|
import io.metersphere.ldap.domain.LdapInfo;
|
||||||
import io.metersphere.service.SystemParameterService;
|
import io.metersphere.service.SystemParameterService;
|
||||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||||
|
@ -41,6 +42,18 @@ public class SystemParameterController {
|
||||||
return SystemParameterService.mailInfo(ParamConstants.Classify.MAIL.getValue());
|
return SystemParameterService.mailInfo(ParamConstants.Classify.MAIL.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/base/info")
|
||||||
|
@RequiresRoles(value = {RoleConstants.ADMIN})
|
||||||
|
public BaseSystemConfigDTO getBaseInfo () {
|
||||||
|
return SystemParameterService.getBaseInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/save/base")
|
||||||
|
@RequiresRoles(value = {RoleConstants.ADMIN})
|
||||||
|
public void saveBaseInfo (@RequestBody List<SystemParameter> systemParameter) {
|
||||||
|
SystemParameterService.saveBaseInfo(systemParameter);
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/save/ldap")
|
@PostMapping("/save/ldap")
|
||||||
@RequiresRoles(value = {RoleConstants.ADMIN})
|
@RequiresRoles(value = {RoleConstants.ADMIN})
|
||||||
public void saveLdap(@RequestBody List<SystemParameter> systemParameter) {
|
public void saveLdap(@RequestBody List<SystemParameter> systemParameter) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package io.metersphere.controller;
|
package io.metersphere.controller;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import io.metersphere.base.domain.User;
|
||||||
import io.metersphere.commons.utils.SessionUtils;
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
@ -15,7 +16,8 @@ public class TestController {
|
||||||
|
|
||||||
|
|
||||||
@PostMapping(value = "/upload", consumes = {"multipart/form-data"})
|
@PostMapping(value = "/upload", consumes = {"multipart/form-data"})
|
||||||
public Object testUpload(@RequestPart(value = "id") String id, @RequestPart(value = "file") MultipartFile file, @RequestPart(value = "files") List<MultipartFile> bodyFiles) {
|
public Object testUpload(@RequestPart(value = "id") String id, @RequestPart(value = "file") MultipartFile file, @RequestPart(value = "files") List<MultipartFile> bodyFiles
|
||||||
|
, @RequestPart(value = "user") User user, @RequestParam(value = "name") String name) {
|
||||||
JSONObject jsonObject = new JSONObject();
|
JSONObject jsonObject = new JSONObject();
|
||||||
jsonObject.put("id", id);
|
jsonObject.put("id", id);
|
||||||
jsonObject.put("file", file.getOriginalFilename());
|
jsonObject.put("file", file.getOriginalFilename());
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package io.metersphere.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class BaseSystemConfigDTO {
|
||||||
|
private String url;
|
||||||
|
}
|
|
@ -1,8 +1,7 @@
|
||||||
package io.metersphere.notice.controller;
|
package io.metersphere.notice.controller;
|
||||||
|
|
||||||
import io.metersphere.base.domain.Notice;
|
|
||||||
import io.metersphere.notice.controller.request.NoticeRequest;
|
import io.metersphere.notice.controller.request.NoticeRequest;
|
||||||
import io.metersphere.notice.service.MailService;
|
import io.metersphere.notice.domain.NoticeDetail;
|
||||||
import io.metersphere.notice.service.NoticeService;
|
import io.metersphere.notice.service.NoticeService;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@ -21,7 +20,7 @@ public class NoticeController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/query/{testId}")
|
@GetMapping("/query/{testId}")
|
||||||
public List<Notice> queryNotice(@PathVariable String testId) {
|
public List<NoticeDetail> queryNotice(@PathVariable String testId) {
|
||||||
return noticeService.queryNotice(testId);
|
return noticeService.queryNotice(testId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package io.metersphere.notice.controller.request;
|
package io.metersphere.notice.controller.request;
|
||||||
|
|
||||||
import io.metersphere.base.domain.Notice;
|
import io.metersphere.notice.domain.NoticeDetail;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class NoticeRequest extends Notice {
|
public class NoticeRequest extends NoticeDetail {
|
||||||
private String testId;
|
private String testId;
|
||||||
private List<Notice> notices;
|
private List<NoticeDetail> notices;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package io.metersphere.notice.domain;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.Notice;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class NoticeDetail extends Notice {
|
||||||
|
private String[] names;
|
||||||
|
|
||||||
|
private String[] emails;
|
||||||
|
|
||||||
|
private String event;
|
||||||
|
|
||||||
|
private String testId;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
private String enable;
|
||||||
|
}
|
|
@ -1,21 +1,23 @@
|
||||||
package io.metersphere.notice.service;
|
package io.metersphere.notice.service;
|
||||||
|
|
||||||
import io.metersphere.api.dto.APIReportResult;
|
import io.metersphere.api.dto.APIReportResult;
|
||||||
import io.metersphere.base.domain.Notice;
|
|
||||||
import io.metersphere.base.domain.SystemParameter;
|
import io.metersphere.base.domain.SystemParameter;
|
||||||
import io.metersphere.base.domain.TestCaseWithBLOBs;
|
import io.metersphere.base.domain.TestCaseWithBLOBs;
|
||||||
import io.metersphere.commons.constants.ParamConstants;
|
import io.metersphere.commons.constants.ParamConstants;
|
||||||
import io.metersphere.commons.utils.EncryptUtils;
|
import io.metersphere.commons.utils.EncryptUtils;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
import io.metersphere.dto.BaseSystemConfigDTO;
|
||||||
import io.metersphere.dto.LoadTestDTO;
|
import io.metersphere.dto.LoadTestDTO;
|
||||||
import io.metersphere.i18n.Translator;
|
import io.metersphere.i18n.Translator;
|
||||||
|
import io.metersphere.notice.domain.NoticeDetail;
|
||||||
import io.metersphere.service.SystemParameterService;
|
import io.metersphere.service.SystemParameterService;
|
||||||
import io.metersphere.service.UserService;
|
import io.metersphere.service.UserService;
|
||||||
import io.metersphere.track.request.testreview.SaveCommentRequest;
|
import io.metersphere.track.request.testreview.SaveCommentRequest;
|
||||||
import io.metersphere.track.request.testreview.SaveTestCaseReviewRequest;
|
import io.metersphere.track.request.testreview.SaveTestCaseReviewRequest;
|
||||||
import org.apache.commons.collections4.MapUtils;
|
import org.apache.commons.collections4.MapUtils;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.flywaydb.core.internal.util.StringUtils;
|
import org.apache.commons.lang3.RegExUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.mail.MailException;
|
import org.springframework.mail.MailException;
|
||||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||||
|
@ -36,7 +38,9 @@ public class MailService {
|
||||||
@Resource
|
@Resource
|
||||||
private SystemParameterService systemParameterService;
|
private SystemParameterService systemParameterService;
|
||||||
|
|
||||||
public void sendHtml(String id, List<Notice> notice, String status, String type) {
|
|
||||||
|
public void sendHtml(String id, List<NoticeDetail> notice, String status, String type) {
|
||||||
|
BaseSystemConfigDTO baseSystemConfigDTO = systemParameterService.getBaseInfo();
|
||||||
JavaMailSenderImpl javaMailSender = getMailSender();
|
JavaMailSenderImpl javaMailSender = getMailSender();
|
||||||
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
|
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
|
||||||
String testName = "";
|
String testName = "";
|
||||||
|
@ -46,16 +50,19 @@ public class MailService {
|
||||||
} else if (type.equals("performance")) {
|
} else if (type.equals("performance")) {
|
||||||
LoadTestDTO performanceResult = apiAndPerformanceHelper.getPerformance(id);
|
LoadTestDTO performanceResult = apiAndPerformanceHelper.getPerformance(id);
|
||||||
testName = performanceResult.getName();
|
testName = performanceResult.getName();
|
||||||
status = performanceResult.getStatus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, String> context = new HashMap<>();
|
Map<String, String> context = new HashMap<>();
|
||||||
context.put("title", type + Translator.get("timing_task_result_notification"));
|
context.put("title", type + Translator.get("timing_task_result_notification"));
|
||||||
context.put("testName", testName);
|
context.put("testName", testName);
|
||||||
|
context.put("url", baseSystemConfigDTO.getUrl());
|
||||||
|
context.put("id", id);
|
||||||
|
context.put("type", type);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String failTemplate = IOUtils.toString(this.getClass().getResource("/mail/fail.html"), StandardCharsets.UTF_8);
|
String failTemplate = IOUtils.toString(this.getClass().getResource("/mail/fail.html"), StandardCharsets.UTF_8);
|
||||||
String successTemplate = IOUtils.toString(this.getClass().getResource("/mail/success.html"), StandardCharsets.UTF_8);
|
String successTemplate = IOUtils.toString(this.getClass().getResource("/mail/success.html"), StandardCharsets.UTF_8);
|
||||||
|
String successPerformanceTemplate = IOUtils.toString(this.getClass().getResource("/mail/successPerformance.html"), StandardCharsets.UTF_8);
|
||||||
|
|
||||||
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
|
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
|
||||||
helper.setFrom(javaMailSender.getUsername());
|
helper.setFrom(javaMailSender.getUsername());
|
||||||
|
@ -64,7 +71,7 @@ public class MailService {
|
||||||
List<String> successEmailList = new ArrayList<>();
|
List<String> successEmailList = new ArrayList<>();
|
||||||
List<String> failEmailList = new ArrayList<>();
|
List<String> failEmailList = new ArrayList<>();
|
||||||
if (notice.size() > 0) {
|
if (notice.size() > 0) {
|
||||||
for (Notice n : notice) {
|
for (NoticeDetail n : notice) {
|
||||||
if (n.getEnable().equals("true") && n.getEvent().equals("执行成功")) {
|
if (n.getEnable().equals("true") && n.getEvent().equals("执行成功")) {
|
||||||
successEmailList = userService.queryEmail(n.getNames());
|
successEmailList = userService.queryEmail(n.getNames());
|
||||||
}
|
}
|
||||||
|
@ -79,6 +86,9 @@ public class MailService {
|
||||||
if (status.equals("Success")) {
|
if (status.equals("Success")) {
|
||||||
users = successEmailList.toArray(new String[0]);
|
users = successEmailList.toArray(new String[0]);
|
||||||
helper.setText(getContent(successTemplate, context), true);
|
helper.setText(getContent(successTemplate, context), true);
|
||||||
|
} else if (status.equals("Starting") && type.equals("performance")) {
|
||||||
|
users = successEmailList.toArray(new String[0]);
|
||||||
|
helper.setText(getContent(successPerformanceTemplate, context), true);
|
||||||
} else {
|
} else {
|
||||||
users = failEmailList.toArray(new String[0]);
|
users = failEmailList.toArray(new String[0]);
|
||||||
helper.setText(getContent(failTemplate, context), true);
|
helper.setText(getContent(failTemplate, context), true);
|
||||||
|
@ -96,17 +106,18 @@ public class MailService {
|
||||||
|
|
||||||
private String getContent(String template, Map<String, String> context) {
|
private String getContent(String template, Map<String, String> context) {
|
||||||
if (MapUtils.isNotEmpty(context)) {
|
if (MapUtils.isNotEmpty(context)) {
|
||||||
context.forEach((k, v) -> {
|
for (String k : context.keySet()) {
|
||||||
if (v != null && !v.isEmpty()) {
|
if (StringUtils.isNotBlank(context.get(k))) {
|
||||||
StringUtils.replaceAll(template, "${" + k + "}", v);
|
template = RegExUtils.replaceAll(template, "\\$\\{" + k + "}", context.get(k));
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void sendHtml(List<String> userIds, String type, SaveTestCaseReviewRequest reviewRequest, SaveCommentRequest request, TestCaseWithBLOBs testCaseWithBLOBs) {
|
public void sendHtml(List<String> userIds, String type, SaveTestCaseReviewRequest reviewRequest, SaveCommentRequest request, TestCaseWithBLOBs testCaseWithBLOBs) {
|
||||||
|
BaseSystemConfigDTO baseSystemConfigDTO = systemParameterService.getBaseInfo();
|
||||||
Long startTime = reviewRequest.getCreateTime();
|
Long startTime = reviewRequest.getCreateTime();
|
||||||
Long endTime = reviewRequest.getEndTime();
|
Long endTime = reviewRequest.getEndTime();
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
@ -131,6 +142,8 @@ public class MailService {
|
||||||
context.put("description", request.getDescription());
|
context.put("description", request.getDescription());
|
||||||
context.put("start", start);
|
context.put("start", start);
|
||||||
context.put("end", end);
|
context.put("end", end);
|
||||||
|
context.put("url", baseSystemConfigDTO.getUrl());
|
||||||
|
context.put("id", reviewRequest.getId());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String reviewerTemplate = IOUtils.toString(this.getClass().getResource("/mail/reviewer.html"), StandardCharsets.UTF_8);
|
String reviewerTemplate = IOUtils.toString(this.getClass().getResource("/mail/reviewer.html"), StandardCharsets.UTF_8);
|
||||||
|
|
|
@ -4,12 +4,11 @@ import io.metersphere.base.domain.Notice;
|
||||||
import io.metersphere.base.domain.NoticeExample;
|
import io.metersphere.base.domain.NoticeExample;
|
||||||
import io.metersphere.base.mapper.NoticeMapper;
|
import io.metersphere.base.mapper.NoticeMapper;
|
||||||
import io.metersphere.notice.controller.request.NoticeRequest;
|
import io.metersphere.notice.controller.request.NoticeRequest;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import io.metersphere.notice.domain.NoticeDetail;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@ -66,17 +65,17 @@ public class NoticeService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Notice> queryNotice(String id) {
|
public List<NoticeDetail> queryNotice(String id) {
|
||||||
NoticeExample example = new NoticeExample();
|
NoticeExample example = new NoticeExample();
|
||||||
example.createCriteria().andTestIdEqualTo(id);
|
example.createCriteria().andTestIdEqualTo(id);
|
||||||
List<Notice> notices = noticeMapper.selectByExample(example);
|
List<Notice> notices = noticeMapper.selectByExample(example);
|
||||||
List<Notice> notice = new ArrayList<>();
|
List<NoticeDetail> notice = new ArrayList<>();
|
||||||
List<String> success = new ArrayList<>();
|
List<String> success = new ArrayList<>();
|
||||||
List<String> fail = new ArrayList<>();
|
List<String> fail = new ArrayList<>();
|
||||||
String[] successArray = new String[success.size()];
|
String[] successArray = new String[success.size()];
|
||||||
String[] failArray = new String[fail.size()];
|
String[] failArray = new String[fail.size()];
|
||||||
Notice notice1 = new Notice();
|
NoticeDetail notice1 = new NoticeDetail();
|
||||||
Notice notice2 = new Notice();
|
NoticeDetail notice2 = new NoticeDetail();
|
||||||
if (notices.size() > 0) {
|
if (notices.size() > 0) {
|
||||||
for (Notice n : notices) {
|
for (Notice n : notices) {
|
||||||
if (n.getEvent().equals("执行成功")) {
|
if (n.getEvent().equals("执行成功")) {
|
||||||
|
|
|
@ -19,6 +19,7 @@ import io.metersphere.dto.LoadTestDTO;
|
||||||
import io.metersphere.dto.ScheduleDao;
|
import io.metersphere.dto.ScheduleDao;
|
||||||
import io.metersphere.i18n.Translator;
|
import io.metersphere.i18n.Translator;
|
||||||
import io.metersphere.job.sechedule.PerformanceTestJob;
|
import io.metersphere.job.sechedule.PerformanceTestJob;
|
||||||
|
import io.metersphere.notice.domain.NoticeDetail;
|
||||||
import io.metersphere.notice.service.MailService;
|
import io.metersphere.notice.service.MailService;
|
||||||
import io.metersphere.notice.service.NoticeService;
|
import io.metersphere.notice.service.NoticeService;
|
||||||
import io.metersphere.performance.engine.Engine;
|
import io.metersphere.performance.engine.Engine;
|
||||||
|
@ -237,19 +238,6 @@ public class PerformanceTestService {
|
||||||
}
|
}
|
||||||
|
|
||||||
startEngine(loadTest, engine, request.getTriggerMode());
|
startEngine(loadTest, engine, request.getTriggerMode());
|
||||||
/* if (request.getTriggerMode().equals("SCHEDULE")) {
|
|
||||||
List<Notice> notice = null;
|
|
||||||
try {
|
|
||||||
notice = noticeService.queryNotice(request.getId());
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
mailService.sendHtml(engine.getReportId(), notice, "status", "performance");
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
return engine.getReportId();
|
return engine.getReportId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,6 +305,19 @@ public class PerformanceTestService {
|
||||||
reportResult.setReportKey(ReportKeys.ResultStatus.name());
|
reportResult.setReportKey(ReportKeys.ResultStatus.name());
|
||||||
reportResult.setReportValue("Ready"); // 初始化一个 result_status, 这个值用在data-streaming中
|
reportResult.setReportValue("Ready"); // 初始化一个 result_status, 这个值用在data-streaming中
|
||||||
loadTestReportResultMapper.insertSelective(reportResult);
|
loadTestReportResultMapper.insertSelective(reportResult);
|
||||||
|
if (triggerMode.equals("SCHEDULE")) {
|
||||||
|
List<NoticeDetail> notice = null;
|
||||||
|
try {
|
||||||
|
notice = noticeService.queryNotice(loadTest.getId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.error(e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
mailService.sendHtml(engine.getReportId(), notice, loadTest.getStatus(), "performance");
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (MSException e) {
|
} catch (MSException e) {
|
||||||
LogUtil.error(e);
|
LogUtil.error(e);
|
||||||
loadTest.setStatus(PerformanceTestStatus.Error.name());
|
loadTest.setStatus(PerformanceTestStatus.Error.name());
|
||||||
|
|
|
@ -7,6 +7,7 @@ import io.metersphere.base.mapper.ext.ExtSystemParameterMapper;
|
||||||
import io.metersphere.commons.constants.ParamConstants;
|
import io.metersphere.commons.constants.ParamConstants;
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.utils.EncryptUtils;
|
import io.metersphere.commons.utils.EncryptUtils;
|
||||||
|
import io.metersphere.dto.BaseSystemConfigDTO;
|
||||||
import io.metersphere.i18n.Translator;
|
import io.metersphere.i18n.Translator;
|
||||||
import io.metersphere.ldap.domain.LdapInfo;
|
import io.metersphere.ldap.domain.LdapInfo;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
@ -182,4 +183,30 @@ public class SystemParameterService {
|
||||||
}
|
}
|
||||||
return param.getParamValue();
|
return param.getParamValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BaseSystemConfigDTO getBaseInfo() {
|
||||||
|
BaseSystemConfigDTO baseSystemConfigDTO = new BaseSystemConfigDTO();
|
||||||
|
List<SystemParameter> paramList = this.getParamList(ParamConstants.Classify.BASE.getValue());
|
||||||
|
if (!CollectionUtils.isEmpty(paramList)) {
|
||||||
|
for (SystemParameter param : paramList) {
|
||||||
|
if (StringUtils.equals(param.getParamKey(), ParamConstants.BASE.URL.getValue())) {
|
||||||
|
baseSystemConfigDTO.setUrl(param.getParamValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return baseSystemConfigDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveBaseInfo(List<SystemParameter> parameters) {
|
||||||
|
SystemParameterExample example = new SystemParameterExample();
|
||||||
|
parameters.forEach(param -> {
|
||||||
|
example.createCriteria().andParamKeyEqualTo(param.getParamKey());
|
||||||
|
if (systemParameterMapper.countByExample(example) > 0) {
|
||||||
|
systemParameterMapper.updateByPrimaryKey(param);
|
||||||
|
} else {
|
||||||
|
systemParameterMapper.insert(param);
|
||||||
|
}
|
||||||
|
example.clear();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package io.metersphere.track.service;
|
package io.metersphere.track.service;
|
||||||
|
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.TestCaseComment;
|
||||||
|
import io.metersphere.base.domain.TestCaseCommentExample;
|
||||||
|
import io.metersphere.base.domain.TestCaseWithBLOBs;
|
||||||
|
import io.metersphere.base.domain.User;
|
||||||
import io.metersphere.base.mapper.TestCaseCommentMapper;
|
import io.metersphere.base.mapper.TestCaseCommentMapper;
|
||||||
import io.metersphere.base.mapper.TestCaseMapper;
|
import io.metersphere.base.mapper.TestCaseMapper;
|
||||||
import io.metersphere.base.mapper.TestCaseReviewMapper;
|
import io.metersphere.base.mapper.TestCaseReviewMapper;
|
||||||
|
@ -9,12 +12,10 @@ import io.metersphere.commons.utils.SessionUtils;
|
||||||
import io.metersphere.notice.service.MailService;
|
import io.metersphere.notice.service.MailService;
|
||||||
import io.metersphere.track.request.testreview.SaveCommentRequest;
|
import io.metersphere.track.request.testreview.SaveCommentRequest;
|
||||||
import io.metersphere.track.request.testreview.SaveTestCaseReviewRequest;
|
import io.metersphere.track.request.testreview.SaveTestCaseReviewRequest;
|
||||||
import org.apache.commons.beanutils.BeanUtils;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -60,7 +61,8 @@ public class TestCaseCommentService {
|
||||||
testCaseComments.forEach(testCaseComment -> {
|
testCaseComments.forEach(testCaseComment -> {
|
||||||
String authorId = testCaseComment.getAuthor();
|
String authorId = testCaseComment.getAuthor();
|
||||||
User user = userMapper.selectByPrimaryKey(authorId);
|
User user = userMapper.selectByPrimaryKey(authorId);
|
||||||
testCaseComment.setAuthor(user.getName());
|
String author = user == null ? authorId : user.getName();
|
||||||
|
testCaseComment.setAuthor(author);
|
||||||
});
|
});
|
||||||
return testCaseComments;
|
return testCaseComments;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,13 +10,16 @@ import io.metersphere.commons.constants.TestPlanStatus;
|
||||||
import io.metersphere.commons.constants.TestPlanTestCaseStatus;
|
import io.metersphere.commons.constants.TestPlanTestCaseStatus;
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.user.SessionUser;
|
import io.metersphere.commons.user.SessionUser;
|
||||||
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
import io.metersphere.commons.utils.MathUtils;
|
import io.metersphere.commons.utils.MathUtils;
|
||||||
import io.metersphere.commons.utils.ServiceUtils;
|
import io.metersphere.commons.utils.ServiceUtils;
|
||||||
import io.metersphere.commons.utils.SessionUtils;
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
import io.metersphere.controller.request.member.QueryMemberRequest;
|
import io.metersphere.controller.request.member.QueryMemberRequest;
|
||||||
import io.metersphere.notice.service.MailService;
|
import io.metersphere.notice.service.MailService;
|
||||||
import io.metersphere.service.UserService;
|
import io.metersphere.service.UserService;
|
||||||
import io.metersphere.track.dto.*;
|
import io.metersphere.track.dto.TestCaseReviewDTO;
|
||||||
|
import io.metersphere.track.dto.TestReviewCaseDTO;
|
||||||
|
import io.metersphere.track.dto.TestReviewDTOWithMetric;
|
||||||
import io.metersphere.track.request.testreview.*;
|
import io.metersphere.track.request.testreview.*;
|
||||||
import org.apache.commons.beanutils.BeanUtils;
|
import org.apache.commons.beanutils.BeanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
@ -314,7 +317,7 @@ public class TestCaseReviewService {
|
||||||
testCaseReviewMapper.updateByPrimaryKey(testCaseReview);
|
testCaseReviewMapper.updateByPrimaryKey(testCaseReview);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getTestCaseReviewerIds(String reviewId) {
|
public List<String> getTestCaseReviewerIds(String reviewId) {
|
||||||
TestCaseReviewUsersExample testCaseReviewUsersExample = new TestCaseReviewUsersExample();
|
TestCaseReviewUsersExample testCaseReviewUsersExample = new TestCaseReviewUsersExample();
|
||||||
testCaseReviewUsersExample.createCriteria().andReviewIdEqualTo(reviewId);
|
testCaseReviewUsersExample.createCriteria().andReviewIdEqualTo(reviewId);
|
||||||
|
@ -345,12 +348,13 @@ public class TestCaseReviewService {
|
||||||
TestCaseReview _testCaseReview = testCaseReviewMapper.selectByPrimaryKey(reviewId);
|
TestCaseReview _testCaseReview = testCaseReviewMapper.selectByPrimaryKey(reviewId);
|
||||||
List<String> userIds = new ArrayList<>();
|
List<String> userIds = new ArrayList<>();
|
||||||
userIds.add(_testCaseReview.getCreator());
|
userIds.add(_testCaseReview.getCreator());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
BeanUtils.copyProperties(testCaseReviewRequest, _testCaseReview);
|
BeanUtils.copyProperties(testCaseReviewRequest, _testCaseReview);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
e.printStackTrace();
|
LogUtil.error(e);
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
e.printStackTrace();
|
LogUtil.error(e);
|
||||||
}
|
}
|
||||||
mailService.sendHtml(userIds, "end", testCaseReviewRequest, request, testCaseWithBLOBs);
|
mailService.sendHtml(userIds, "end", testCaseReviewRequest, request, testCaseWithBLOBs);
|
||||||
testCaseReviewMapper.updateByPrimaryKeySelective(testCaseReview);
|
testCaseReviewMapper.updateByPrimaryKeySelective(testCaseReview);
|
||||||
|
|
|
@ -95,6 +95,10 @@ public class TestPlanService {
|
||||||
|
|
||||||
testPlan.setId(testPlanId);
|
testPlan.setId(testPlanId);
|
||||||
testPlan.setStatus(TestPlanStatus.Prepare.name());
|
testPlan.setStatus(TestPlanStatus.Prepare.name());
|
||||||
|
testPlan.setPlannedStartTime(System.currentTimeMillis());
|
||||||
|
testPlan.setPlannedEndTime(System.currentTimeMillis());
|
||||||
|
testPlan.setActualStartTime(System.currentTimeMillis());
|
||||||
|
testPlan.setActualEndTime(System.currentTimeMillis());
|
||||||
testPlan.setCreateTime(System.currentTimeMillis());
|
testPlan.setCreateTime(System.currentTimeMillis());
|
||||||
testPlan.setUpdateTime(System.currentTimeMillis());
|
testPlan.setUpdateTime(System.currentTimeMillis());
|
||||||
testPlanMapper.insert(testPlan);
|
testPlanMapper.insert(testPlan);
|
||||||
|
@ -115,7 +119,17 @@ public class TestPlanService {
|
||||||
editTestPlanProject(testPlan);
|
editTestPlanProject(testPlan);
|
||||||
testPlan.setUpdateTime(System.currentTimeMillis());
|
testPlan.setUpdateTime(System.currentTimeMillis());
|
||||||
checkTestPlanExist(testPlan);
|
checkTestPlanExist(testPlan);
|
||||||
return testPlanMapper.updateByPrimaryKeySelective(testPlan);
|
//进行中状态,写入实际开始时间
|
||||||
|
if ("Underway".equals(testPlan.getStatus())) {
|
||||||
|
testPlan.setActualStartTime(System.currentTimeMillis());
|
||||||
|
return testPlanMapper.updateByPrimaryKeySelective(testPlan);
|
||||||
|
} else if("Completed".equals(testPlan.getStatus())){
|
||||||
|
//已完成,写入实际完成时间
|
||||||
|
testPlan.setActualEndTime(System.currentTimeMillis());
|
||||||
|
return testPlanMapper.updateByPrimaryKeySelective(testPlan);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void editTestPlanProject(TestPlanDTO testPlan) {
|
private void editTestPlanProject(TestPlanDTO testPlan) {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit cf6b06526324326a563d933e07118fac014a63b4
|
Subproject commit c2dacf960cdb1ed35664bdd3432120b1203b73d8
|
|
@ -0,0 +1 @@
|
||||||
|
INSERT into system_parameter values('base.url', 'http://localhost:8081', 'text', 1);
|
|
@ -0,0 +1,4 @@
|
||||||
|
ALTER TABLE test_plan ADD planned_start_time bigint(13) NULL COMMENT 'Planned start time timestamp';
|
||||||
|
ALTER TABLE test_plan ADD planned_end_time bigint(13) NULL COMMENT 'Planned end time timestamp';
|
||||||
|
ALTER TABLE test_plan ADD actual_start_time bigint(13) NULL COMMENT 'Actual start time timestamp';
|
||||||
|
ALTER TABLE test_plan ADD actual_end_time bigint(13) NULL COMMENT 'Actual end time timestamp';
|
|
@ -155,5 +155,5 @@ email_subject=Metersphere timing task result notification
|
||||||
import_xmind_count_error=The number of use cases imported into the mind map cannot exceed 500
|
import_xmind_count_error=The number of use cases imported into the mind map cannot exceed 500
|
||||||
import_xmind_not_found=Test case not found
|
import_xmind_not_found=Test case not found
|
||||||
license_valid_license_error=Authorization authentication failed
|
license_valid_license_error=Authorization authentication failed
|
||||||
timing_task_result_notification="Timing task result notification"
|
timing_task_result_notification=Timing task result notification
|
||||||
test_review_task_notice="Test review task notice"
|
test_review_task_notice=Test review task notice
|
||||||
|
|
|
@ -155,7 +155,7 @@ email_subject=MeterSphere定时任务结果通知
|
||||||
import_xmind_count_error=思维导图导入用例数量不能超过 500 条
|
import_xmind_count_error=思维导图导入用例数量不能超过 500 条
|
||||||
license_valid_license_error=授权认证失败
|
license_valid_license_error=授权认证失败
|
||||||
import_xmind_not_found=未找到测试用例
|
import_xmind_not_found=未找到测试用例
|
||||||
timing_task_result_notification="定时任务结果通知"
|
timing_task_result_notification=定时任务结果通知
|
||||||
test_review_task_notice="测试评审任务通知"
|
test_review_task_notice=测试评审任务通知
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -156,5 +156,5 @@ license_valid_license_code=授權碼已經存在
|
||||||
email_subject=MeterSphere定時任務結果通知
|
email_subject=MeterSphere定時任務結果通知
|
||||||
import_xmind_count_error=思維導圖導入用例數量不能超過 500 條
|
import_xmind_count_error=思維導圖導入用例數量不能超過 500 條
|
||||||
import_xmind_not_found=未找到测试用例
|
import_xmind_not_found=未找到测试用例
|
||||||
timing_task_result_notification="定時任務結果通知"
|
timing_task_result_notification=定時任務結果通知
|
||||||
test_review_task_notice="測試評審任務通知"
|
test_review_task_notice=測試評審任務通知
|
|
@ -4,9 +4,13 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>MeterSphere</title>
|
<title>MeterSphere</title>
|
||||||
</head>
|
</head>
|
||||||
<body style="text-align: left">
|
<body>
|
||||||
<div>
|
<div>
|
||||||
<p>${maintainer} 发起的</p><br/> ${testCaseName} </p><br/>添加评论:${description} </p>
|
<p style="text-align: left"> ${maintainer} 发起的<br/>
|
||||||
|
${testCaseName}<br/>
|
||||||
|
添加评论:${description}<br/>
|
||||||
|
点击下面链接进入用例评审页面</p>
|
||||||
|
<a href="${url}/#/track/review/view">${url}/#/track/review/view</a>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -4,9 +4,15 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>MeterSphere</title>
|
<title>MeterSphere</title>
|
||||||
</head>
|
</head>
|
||||||
<body style="text-align: left">
|
<body>
|
||||||
<div>
|
<div>
|
||||||
<p>${creator} 发起的:</p><br/>${reviewName} </p><br/>计划开始时间是 ${start}, 计划结束时间为 ${end} 已完成</p>
|
<p style="text-align: left">${creator} 发起的:<br>
|
||||||
|
${reviewName}<br>
|
||||||
|
计划开始时间是:${start}<br>
|
||||||
|
计划结束时间为:${end}<br>
|
||||||
|
已完成<br>
|
||||||
|
点击下面链接进入用例评审页面</p>
|
||||||
|
<a href="${url}/#/track/review/view">${url}/#/track/review/view</a>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -4,12 +4,21 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>MeterSphere</title>
|
<title>MeterSphere</title>
|
||||||
</head>
|
</head>
|
||||||
<body style="text-align: left">
|
<body>
|
||||||
<div>
|
<div>
|
||||||
<h3>${title}</h3>
|
<div style="text-align: left">
|
||||||
<p>尊敬的用户:您好,
|
<h3>${title}</h3>
|
||||||
<p><br/>
|
</div>
|
||||||
<p>您所执行的 ${testName} 运行失败</p>
|
<div style="text-align: left">
|
||||||
|
<p>尊敬的用户:</p>
|
||||||
|
<p style="margin-left: 60px">您好:
|
||||||
|
</div>
|
||||||
|
<div style="margin-left: 100px">
|
||||||
|
<p>您所执行的 ${testName} 运行失败<br/>
|
||||||
|
请点击下面链接进入测试报告页面</p>
|
||||||
|
<a href="${url}/#/${type}/report/view/${id}">${url}/#/${type}/report/view/${id}</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -4,9 +4,15 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>MeterSphere</title>
|
<title>MeterSphere</title>
|
||||||
</head>
|
</head>
|
||||||
<body style="text-align: left">
|
<body>
|
||||||
<div>
|
<div>
|
||||||
<p>${creator} 发起的:</p><br/>${reviewName} </p><br/>计划开始时间是 ${start},计划结束时间为 ${end} 请跟进</p>
|
<p style="text-align: left">${creator} 发起的:<br>
|
||||||
|
${reviewName}<br>
|
||||||
|
计划开始时间是:${start}<br>
|
||||||
|
计划结束时间为:${end}<br>
|
||||||
|
请跟进<br>
|
||||||
|
点击下面链接进入评审页面进行审核</p>
|
||||||
|
<a href="${url}/#/track/review/view/${id}">${url}/#/track/review/view/${id}</a>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -5,11 +5,17 @@
|
||||||
<title>MeterSphere</title>
|
<title>MeterSphere</title>
|
||||||
</head>
|
</head>
|
||||||
<body style="text-align: left">
|
<body style="text-align: left">
|
||||||
<div>
|
<div style="text-align: left">
|
||||||
<h3>${title}</h3>
|
<h3>${title}</h3>
|
||||||
<p>尊敬的用户:您好,
|
</div>
|
||||||
<p><br/>
|
<div style="text-align: left">
|
||||||
<p>您所执行的 ${testName} 运行成功</p>
|
<p>尊敬的用户:</p>
|
||||||
|
<p style="margin-left: 60px">您好:
|
||||||
|
</div>
|
||||||
|
<div style="margin-left: 100px">
|
||||||
|
<p>您所执行的 ${testName} 运行成功<br/>
|
||||||
|
请点击下面链接进入测试报告页面</p>
|
||||||
|
<a href="${url}/#/${type}/report/view/${id}">${url}/#/${type}/report/view/${id}</a>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -0,0 +1,21 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>MeterSphere</title>
|
||||||
|
</head>
|
||||||
|
<body style="text-align: left">
|
||||||
|
<div style="text-align: left">
|
||||||
|
<h3>${title}</h3>
|
||||||
|
</div>
|
||||||
|
<div style="text-align: left">
|
||||||
|
<p>尊敬的用户:</p>
|
||||||
|
<p style="margin-left: 60px">您好:
|
||||||
|
</div>
|
||||||
|
<div style="margin-left: 100px">
|
||||||
|
<p>您所执行的 ${testName} 性能测试已完成<br/>
|
||||||
|
请点击下面链接进入测试报告页面</p>
|
||||||
|
<a href="${url}/#/${type}/report/view/${id}">${url}/#/${type}/report/view/${id}</a>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -6,8 +6,8 @@
|
||||||
<div class="kv-row" v-for="(item, index) in items" :key="index">
|
<div class="kv-row" v-for="(item, index) in items" :key="index">
|
||||||
<el-row type="flex" :gutter="20" justify="space-between" align="middle">
|
<el-row type="flex" :gutter="20" justify="space-between" align="middle">
|
||||||
<el-col v-if="isShowEnable" class="kv-checkbox">
|
<el-col v-if="isShowEnable" class="kv-checkbox">
|
||||||
<input type="checkbox" v-if="!isDisable(index)" @change="change" :value="item.uuid" v-model="checkedValues"
|
<input type="checkbox" v-if="!isDisable(index)" v-model="item.enable"
|
||||||
:disabled="isDisable(index) || isReadOnly"/>
|
:disabled="isReadOnly"/>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col>
|
<el-col>
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
checkedValues: []
|
// checkedValues: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -79,10 +79,6 @@
|
||||||
let isNeedCreate = true;
|
let isNeedCreate = true;
|
||||||
let removeIndex = -1;
|
let removeIndex = -1;
|
||||||
this.items.forEach((item, index) => {
|
this.items.forEach((item, index) => {
|
||||||
// 启用行赋值
|
|
||||||
if (this.isShowEnable) {
|
|
||||||
item.enable = this.checkedValues.indexOf(item.uuid) != -1 ? true : false;
|
|
||||||
}
|
|
||||||
if (!item.name && !item.value) {
|
if (!item.name && !item.value) {
|
||||||
// 多余的空行
|
// 多余的空行
|
||||||
if (index !== this.items.length - 1) {
|
if (index !== this.items.length - 1) {
|
||||||
|
@ -93,13 +89,7 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (isNeedCreate) {
|
if (isNeedCreate) {
|
||||||
// 往后台送入的复选框值布尔值
|
this.items.push(new KeyValue({enable: true}));
|
||||||
if (this.isShowEnable) {
|
|
||||||
this.items[this.items.length - 1].enable = true;
|
|
||||||
// v-model 选中状态
|
|
||||||
this.checkedValues.push(this.items[this.items.length - 1].uuid);
|
|
||||||
}
|
|
||||||
this.items.push(new KeyValue());
|
|
||||||
}
|
}
|
||||||
this.$emit('change', this.items);
|
this.$emit('change', this.items);
|
||||||
// TODO 检查key重复
|
// TODO 检查key重复
|
||||||
|
@ -112,9 +102,6 @@
|
||||||
let results = queryString ? suggestions.filter(this.createFilter(queryString)) : suggestions;
|
let results = queryString ? suggestions.filter(this.createFilter(queryString)) : suggestions;
|
||||||
cb(results);
|
cb(results);
|
||||||
},
|
},
|
||||||
uuid: function () {
|
|
||||||
return (((1 + Math.random()) * 0x100000) | 0).toString(16).substring(1);
|
|
||||||
},
|
|
||||||
createFilter(queryString) {
|
createFilter(queryString) {
|
||||||
return (restaurant) => {
|
return (restaurant) => {
|
||||||
return (restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
|
return (restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
|
||||||
|
@ -123,15 +110,7 @@
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
if (this.items.length === 0) {
|
if (this.items.length === 0) {
|
||||||
this.items.push(new KeyValue());
|
this.items.push(new KeyValue({enable: true}));
|
||||||
} else if (this.isShowEnable) {
|
|
||||||
this.items.forEach((item, index) => {
|
|
||||||
let uuid = this.uuid();
|
|
||||||
item.uuid = uuid;
|
|
||||||
if (item.enable) {
|
|
||||||
this.checkedValues.push(uuid);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,26 +3,27 @@
|
||||||
<span class="kv-description" v-if="description">
|
<span class="kv-description" v-if="description">
|
||||||
{{ description }}
|
{{ description }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div class="kv-row" v-for="(item, index) in parameters" :key="index">
|
<div class="kv-row" v-for="(item, index) in parameters" :key="index">
|
||||||
<el-row type="flex" :gutter="20" justify="space-between" align="middle">
|
<el-row type="flex" :gutter="20" justify="space-between" align="middle">
|
||||||
|
|
||||||
<el-col class="kv-checkbox">
|
<el-col class="kv-checkbox">
|
||||||
<input type="checkbox" v-if="!isDisable(index)" @change="change" :value="item.uuid" v-model="checkedValues"
|
<input type="checkbox" v-if="!isDisable(index)" v-model="item.enable"
|
||||||
:disabled="isDisable(index) || isReadOnly"/>
|
:disabled="isReadOnly"/>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col>
|
<el-col>
|
||||||
|
|
||||||
<el-input v-if="!suggestions" :disabled="isReadOnly" v-model="item.name" size="small" maxlength="200"
|
<el-input v-if="!suggestions" :disabled="isReadOnly" v-model="item.name" size="small" maxlength="200"
|
||||||
@change="change" :placeholder="keyText" show-word-limit>
|
@change="change" :placeholder="keyText" show-word-limit>
|
||||||
<template v-slot:prepend>
|
<template v-slot:prepend>
|
||||||
<el-select v-if="type === 'body'" :disabled="isReadOnly" class="kv-type" v-model="item.type">
|
<el-select v-if="type === 'body'" :disabled="isReadOnly" class="kv-type" v-model="item.type" @change="typeChange(item)">
|
||||||
<el-option value="text"/>
|
<el-option value="text"/>
|
||||||
<el-option value="file"/>
|
<el-option value="file"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
|
|
||||||
<el-autocomplete :disabled="isReadOnly" :maxlength="200" v-if="suggestions" v-model="item.name" size="small"
|
<el-autocomplete :disabled="isReadOnly" v-if="suggestions" v-model="item.name" size="small"
|
||||||
:fetch-suggestions="querySearch" @change="change" :placeholder="keyText" show-word-limit/>
|
:fetch-suggestions="querySearch" @change="change" :placeholder="keyText" show-word-limit/>
|
||||||
|
|
||||||
</el-col>
|
</el-col>
|
||||||
|
@ -44,6 +45,13 @@
|
||||||
<el-col v-if="item.type === 'file'">
|
<el-col v-if="item.type === 'file'">
|
||||||
<ms-api-body-file-upload :parameter="item"/>
|
<ms-api-body-file-upload :parameter="item"/>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
|
<el-col v-if="type === 'body'">
|
||||||
|
<el-input :disabled="isReadOnly" v-model="item.contentType" size="small" maxlength="100"
|
||||||
|
@change="change" :placeholder="$t('api_test.request.content_type')" show-word-limit>
|
||||||
|
</el-input>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
<el-col class="kv-delete">
|
<el-col class="kv-delete">
|
||||||
<el-button size="mini" class="el-icon-delete-solid" circle @click="remove(index)"
|
<el-button size="mini" class="el-icon-delete-solid" circle @click="remove(index)"
|
||||||
:disabled="isDisable(index) || isReadOnly"/>
|
:disabled="isDisable(index) || isReadOnly"/>
|
||||||
|
@ -85,7 +93,6 @@
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
currentItem: null,
|
currentItem: null,
|
||||||
checkedValues: []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -98,9 +105,6 @@
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
remove: function (index) {
|
remove: function (index) {
|
||||||
// 移除勾选内容
|
|
||||||
let checkIndex = this.checkedValues.indexOf(this.parameters[index].uuid);
|
|
||||||
checkIndex != -1 ? this.checkedValues.splice(checkIndex, 1) : this.checkedValues;
|
|
||||||
// 移除整行输入控件及内容
|
// 移除整行输入控件及内容
|
||||||
this.parameters.splice(index, 1);
|
this.parameters.splice(index, 1);
|
||||||
this.$emit('change', this.parameters);
|
this.$emit('change', this.parameters);
|
||||||
|
@ -109,9 +113,6 @@
|
||||||
let isNeedCreate = true;
|
let isNeedCreate = true;
|
||||||
let removeIndex = -1;
|
let removeIndex = -1;
|
||||||
this.parameters.forEach((item, index) => {
|
this.parameters.forEach((item, index) => {
|
||||||
// 启用行赋值
|
|
||||||
item.enable = this.checkedValues.indexOf(item.uuid) != -1 ? true : false;
|
|
||||||
|
|
||||||
if (!item.name && !item.value) {
|
if (!item.name && !item.value) {
|
||||||
// 多余的空行
|
// 多余的空行
|
||||||
if (index !== this.parameters.length - 1) {
|
if (index !== this.parameters.length - 1) {
|
||||||
|
@ -122,11 +123,7 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (isNeedCreate) {
|
if (isNeedCreate) {
|
||||||
// 往后台送入的复选框值布尔值
|
this.parameters.push(new KeyValue({type: 'text', enable: true, uuid: this.uuid(), contentType: 'text/plain'}));
|
||||||
this.parameters[this.parameters.length - 1].enable = true;
|
|
||||||
// v-model 选中状态
|
|
||||||
this.checkedValues.push(this.parameters[this.parameters.length - 1].uuid);
|
|
||||||
this.parameters.push(new KeyValue(null, null, 'text', false, this.uuid()));
|
|
||||||
}
|
}
|
||||||
this.$emit('change', this.parameters);
|
this.$emit('change', this.parameters);
|
||||||
// TODO 检查key重复
|
// TODO 检查key重复
|
||||||
|
@ -161,22 +158,18 @@
|
||||||
advanced(item) {
|
advanced(item) {
|
||||||
this.$refs.variableAdvance.open();
|
this.$refs.variableAdvance.open();
|
||||||
this.currentItem = item;
|
this.currentItem = item;
|
||||||
this.itemValue = '';
|
|
||||||
this.mockVariableFuncs = [];
|
|
||||||
},
|
},
|
||||||
|
typeChange(item) {
|
||||||
|
if (item.type === 'file') {
|
||||||
|
item.contentType = 'application/octet-stream';
|
||||||
|
} else {
|
||||||
|
item.contentType = 'text/plain';
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
if (this.parameters.length === 0) {
|
if (this.parameters.length === 0) {
|
||||||
this.parameters.push(new KeyValue(null, null, 'text', false, this.uuid()));
|
this.parameters.push(new KeyValue( {type: 'text', enable: true, uuid: this.uuid(), contentType: 'text/plain'}));
|
||||||
} else {
|
|
||||||
this.parameters.forEach((item, index) => {
|
|
||||||
let uuid = this.uuid();
|
|
||||||
item.uuid = uuid;
|
|
||||||
if (item.enable) {
|
|
||||||
this.checkedValues.push(uuid);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,7 +173,7 @@ export default {
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
if (this.environment) {
|
if (this.environment) {
|
||||||
let variables = JSON.parse(this.environment.variables);
|
let variables = this.environment.config.commonConfig.variables;
|
||||||
this.environmentParams = [
|
this.environmentParams = [
|
||||||
{
|
{
|
||||||
name: this.environment.name,
|
name: this.environment.name,
|
||||||
|
|
|
@ -105,9 +105,9 @@
|
||||||
|
|
||||||
.api-body-upload {
|
.api-body-upload {
|
||||||
min-height: 32px;
|
min-height: 32px;
|
||||||
/*border: 1px solid #EBEEF5;*/
|
border: 1px solid #EBEEF5;
|
||||||
/*padding: 2px;*/
|
padding: 2px;
|
||||||
/*border-radius: 4px;*/
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-item {
|
.upload-item {
|
||||||
|
|
|
@ -156,7 +156,7 @@ export default {
|
||||||
let url = new URL(urlStr);
|
let url = new URL(urlStr);
|
||||||
url.searchParams.forEach((value, key) => {
|
url.searchParams.forEach((value, key) => {
|
||||||
if (key && value) {
|
if (key && value) {
|
||||||
this.request.parameters.splice(0, 0, new KeyValue(key, value));
|
this.request.parameters.splice(0, 0, new KeyValue({name: name, value: value}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return url;
|
return url;
|
||||||
|
|
|
@ -344,6 +344,9 @@ export class HTTPSamplerArguments extends Element {
|
||||||
}
|
}
|
||||||
elementProp.stringProp('Argument.value', arg.value);
|
elementProp.stringProp('Argument.value', arg.value);
|
||||||
elementProp.stringProp('Argument.metadata', arg.metadata || "=");
|
elementProp.stringProp('Argument.metadata', arg.metadata || "=");
|
||||||
|
if (arg.contentType) {
|
||||||
|
elementProp.stringProp('HTTPArgument.content_type', arg.contentType, "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -363,7 +366,7 @@ export class HTTPsamplerFiles extends Element {
|
||||||
let elementProp = collectionProp.elementProp(arg.value, 'HTTPFileArg');
|
let elementProp = collectionProp.elementProp(arg.value, 'HTTPFileArg');
|
||||||
elementProp.stringProp('File.path', arg.value);
|
elementProp.stringProp('File.path', arg.value);
|
||||||
elementProp.stringProp('File.paramname', arg.name);
|
elementProp.stringProp('File.paramname', arg.name);
|
||||||
elementProp.stringProp('File.mimetype', arg.metadata || "application/octet-stream");
|
elementProp.stringProp('File.mimetype', arg.contentType || "application/octet-stream");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -656,35 +656,18 @@ export class Body extends BaseConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class KeyValue extends BaseConfig {
|
export class KeyValue extends BaseConfig {
|
||||||
constructor() {
|
constructor(options) {
|
||||||
let options, key, value, type, enable, uuid;
|
options = options || {};
|
||||||
if (arguments.length === 1) {
|
options.enable = options.enable != false ? true : false;
|
||||||
options = arguments[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments.length === 2) {
|
|
||||||
key = arguments[0];
|
|
||||||
value = arguments[1];
|
|
||||||
}
|
|
||||||
if (arguments.length === 3) {
|
|
||||||
key = arguments[0];
|
|
||||||
value = arguments[1];
|
|
||||||
type = arguments[2];
|
|
||||||
}
|
|
||||||
if (arguments.length === 5) {
|
|
||||||
key = arguments[0];
|
|
||||||
value = arguments[1];
|
|
||||||
type = arguments[2];
|
|
||||||
enable = arguments[3];
|
|
||||||
uuid = arguments[4];
|
|
||||||
}
|
|
||||||
super();
|
super();
|
||||||
this.name = key;
|
this.name = undefined;
|
||||||
this.value = value;
|
this.value = undefined;
|
||||||
this.type = type;
|
this.type = undefined;
|
||||||
this.files = undefined;
|
this.files = undefined;
|
||||||
this.enable = enable;
|
this.enable = undefined;
|
||||||
this.uuid = uuid;
|
this.uuid = undefined;
|
||||||
|
this.contentType = undefined;
|
||||||
this.set(options);
|
this.set(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -956,7 +939,7 @@ class JMXHttpRequest {
|
||||||
this.domain = environment.config.httpConfig.domain;
|
this.domain = environment.config.httpConfig.domain;
|
||||||
this.port = environment.config.httpConfig.port;
|
this.port = environment.config.httpConfig.port;
|
||||||
this.protocol = environment.config.httpConfig.protocol;
|
this.protocol = environment.config.httpConfig.protocol;
|
||||||
let url = new URL(environment.config.httpConfig.protocol + "://" + environment.config.commonConfig.socket);
|
let url = new URL(environment.config.httpConfig.protocol + "://" + environment.config.httpConfig.socket);
|
||||||
this.path = this.getPostQueryParameters(request, decodeURIComponent(url.pathname + (request.path ? request.path : '')));
|
this.path = this.getPostQueryParameters(request, decodeURIComponent(url.pathname + (request.path ? request.path : '')));
|
||||||
}
|
}
|
||||||
this.connectTimeout = request.connectTimeout;
|
this.connectTimeout = request.connectTimeout;
|
||||||
|
@ -1117,7 +1100,7 @@ class JMXGenerator {
|
||||||
}
|
}
|
||||||
envArray.forEach(item => {
|
envArray.forEach(item => {
|
||||||
if (item.name && !keys.has(item.name)) {
|
if (item.name && !keys.has(item.name)) {
|
||||||
target.push(new KeyValue(item.name, item.value));
|
target.push(new KeyValue({name: item.name, value: item.value}));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1294,7 +1277,7 @@ class JMXGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
request.headers.push(new KeyValue('Content-Type', type));
|
request.headers.push(new KeyValue({name: 'Content-Type', value: type}));
|
||||||
}
|
}
|
||||||
|
|
||||||
addRequestArguments(httpSamplerProxy, request) {
|
addRequestArguments(httpSamplerProxy, request) {
|
||||||
|
@ -1323,7 +1306,7 @@ class JMXGenerator {
|
||||||
let files = [];
|
let files = [];
|
||||||
let kvs = this.filterKVFile(request.body.kvs);
|
let kvs = this.filterKVFile(request.body.kvs);
|
||||||
kvs.forEach(kv => {
|
kvs.forEach(kv => {
|
||||||
if (kv.files) {
|
if ((kv.enable != false) && kv.files) {
|
||||||
kv.files.forEach(file => {
|
kv.files.forEach(file => {
|
||||||
let arg = {};
|
let arg = {};
|
||||||
arg.name = kv.name;
|
arg.name = kv.name;
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
<template>
|
||||||
|
<div v-loading="result.loading">
|
||||||
|
<el-form :model="formInline" :rules="rules" ref="formInline" class="demo-form-inline"
|
||||||
|
:disabled="show" v-loading="loading" size="small">
|
||||||
|
<el-row>
|
||||||
|
<el-col>
|
||||||
|
<el-form-item :label="$t('system_config.base.url')" prop="url">
|
||||||
|
<el-input v-model="formInline.url" :placeholder="$t('system_config.base.url_tip')"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<div>
|
||||||
|
<el-button @click="edit" v-if="showEdit" size="small">{{ $t('commons.edit') }}</el-button>
|
||||||
|
<el-button type="success" @click="save('formInline')" v-if="showSave" :disabled="disabledSave" size="small">
|
||||||
|
{{ $t('commons.save') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button @click="cancel" type="info" v-if="showCancel" size="small">{{ $t('commons.cancel') }}</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "BaseSetting",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
formInline: {},
|
||||||
|
input: '',
|
||||||
|
visible: true,
|
||||||
|
result: {},
|
||||||
|
showEdit: true,
|
||||||
|
showSave: false,
|
||||||
|
showCancel: false,
|
||||||
|
show: true,
|
||||||
|
disabledConnection: false,
|
||||||
|
disabledSave: false,
|
||||||
|
loading: false,
|
||||||
|
rules: {
|
||||||
|
url: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: this.$t('system_par'),
|
||||||
|
trigger: ['change', 'blur']
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.query()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
query() {
|
||||||
|
this.result = this.$get("/system/base/info", response => {
|
||||||
|
this.formInline = response.data;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.formInline.clearValidate();
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
edit() {
|
||||||
|
this.showEdit = false;
|
||||||
|
this.showSave = true;
|
||||||
|
this.showCancel = true;
|
||||||
|
this.show = false;
|
||||||
|
},
|
||||||
|
save(formInline) {
|
||||||
|
this.showEdit = true;
|
||||||
|
this.showCancel = false;
|
||||||
|
this.showSave = false;
|
||||||
|
this.show = true;
|
||||||
|
let param = [
|
||||||
|
{paramKey: "base.url", paramValue: this.formInline.url, type: "text", sort: 1},
|
||||||
|
];
|
||||||
|
|
||||||
|
this.$refs[formInline].validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
this.result = this.$post("/system/save/base", param, response => {
|
||||||
|
if (response.success) {
|
||||||
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
} else {
|
||||||
|
this.$message.error(this.$t('commons.save_failed'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
cancel() {
|
||||||
|
this.showEdit = true;
|
||||||
|
this.showCancel = false;
|
||||||
|
this.showSave = false;
|
||||||
|
this.show = true;
|
||||||
|
this.query();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
.el-form {
|
||||||
|
min-height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -1,6 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<el-card>
|
<el-card>
|
||||||
<el-tabs class="system-setting" v-model="activeName">
|
<el-tabs class="system-setting" v-model="activeName">
|
||||||
|
|
||||||
|
<el-tab-pane :label="$t('system_config.base_config')" name="base">
|
||||||
|
<base-setting/>
|
||||||
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="$t('system_parameter_setting.mailbox_service_settings')" name="email">
|
<el-tab-pane :label="$t('system_parameter_setting.mailbox_service_settings')" name="email">
|
||||||
<email-setting/>
|
<email-setting/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
@ -14,15 +18,17 @@
|
||||||
<script>
|
<script>
|
||||||
import EmailSetting from "./EmailSetting";
|
import EmailSetting from "./EmailSetting";
|
||||||
import LdapSetting from "./LdapSetting";
|
import LdapSetting from "./LdapSetting";
|
||||||
|
import BaseSetting from "./BaseSetting";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "SystemParameterSetting",
|
name: "SystemParameterSetting",
|
||||||
components: {
|
components: {
|
||||||
|
BaseSetting,
|
||||||
EmailSetting, LdapSetting
|
EmailSetting, LdapSetting
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
activeName: 'email'
|
activeName: 'base'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
:placeholder="$t('test_track.plan.input_plan_project')"
|
:placeholder="$t('test_track.plan.input_plan_project')"
|
||||||
multiple
|
multiple
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
collapse-tags
|
|
||||||
filterable>
|
filterable>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in projects"
|
v-for="item in projects"
|
||||||
|
@ -69,6 +68,28 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
<!--start:xuxm增加自定义‘计划开始’,‘计划结束’时间字段-->
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="8" :offset="1">
|
||||||
|
<el-form-item
|
||||||
|
:label="$t('test_track.plan.planned_start_time')"
|
||||||
|
:label-width="formLabelWidth"
|
||||||
|
prop="plannedStartTime">
|
||||||
|
<el-date-picker :placeholder="$t('test_track.plan.planned_start_time')" v-model="form.plannedStartTime" type="datetime" value-format="timestamp"></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="11" :offset="2">
|
||||||
|
<el-form-item
|
||||||
|
:label="$t('test_track.plan.planned_end_time')"
|
||||||
|
:label-width="formLabelWidth"
|
||||||
|
prop="plannedEndTime">
|
||||||
|
<el-date-picker :placeholder="$t('test_track.plan.planned_end_time')" v-model="form.plannedEndTime" type="datetime" value-format="timestamp" ></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<!--end:xuxm增加自定义‘计划开始’,‘计划结束’时间字段-->
|
||||||
|
|
||||||
<el-row type="flex" justify="left" style="margin-top: 10px;">
|
<el-row type="flex" justify="left" style="margin-top: 10px;">
|
||||||
<el-col :span="23" :offset="1">
|
<el-col :span="23" :offset="1">
|
||||||
<el-form-item :label="$t('commons.description')" :label-width="formLabelWidth" prop="description">
|
<el-form-item :label="$t('commons.description')" :label-width="formLabelWidth" prop="description">
|
||||||
|
@ -129,7 +150,9 @@ export default {
|
||||||
projectIds: [],
|
projectIds: [],
|
||||||
principal: '',
|
principal: '',
|
||||||
stage: '',
|
stage: '',
|
||||||
description: ''
|
description: '',
|
||||||
|
plannedStartTime: '',
|
||||||
|
plannedEndTime: ''
|
||||||
},
|
},
|
||||||
dbProjectIds: [],
|
dbProjectIds: [],
|
||||||
rules: {
|
rules: {
|
||||||
|
|
|
@ -70,20 +70,38 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
sortable
|
sortable
|
||||||
prop="createTime"
|
prop="plannedStartTime"
|
||||||
:label="$t('commons.create_time')"
|
:label="$t('test_track.plan.planned_start_time')"
|
||||||
show-overflow-tooltip>
|
show-overflow-tooltip>
|
||||||
<template v-slot:default="scope">
|
<template v-slot:default="scope">
|
||||||
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
|
<span>{{ scope.row.plannedStartTime | timestampFormatDate }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
sortable
|
sortable
|
||||||
prop="updateTime"
|
prop="plannedEndTime"
|
||||||
:label="$t('commons.update_time')"
|
:label="$t('test_track.plan.planned_end_time')"
|
||||||
show-overflow-tooltip>
|
show-overflow-tooltip>
|
||||||
<template v-slot:default="scope">
|
<template v-slot:default="scope">
|
||||||
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
<span>{{ scope.row.plannedEndTime | timestampFormatDate }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
sortable
|
||||||
|
prop="actualStartTime"
|
||||||
|
:label="$t('test_track.plan.actual_start_time')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<span>{{ scope.row.actualStartTime | timestampFormatDate }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
sortable
|
||||||
|
prop="actualEndTime"
|
||||||
|
:label="$t('test_track.plan.actual_end_time')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<span>{{ scope.row.actualEndTime | timestampFormatDate }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
|
|
@ -72,6 +72,6 @@ export default {
|
||||||
|
|
||||||
.comment-list {
|
.comment-list {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
height: calc(70vh);
|
height: calc(100vh - 250px);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit cc38137a69a0f20fadece9c0f9f50a9468c4ace9
|
Subproject commit 06d935cd1d22ab36f09763745c2aff8ad3fb08c1
|
|
@ -175,6 +175,13 @@ export default {
|
||||||
invalid: 'invalid',
|
invalid: 'invalid',
|
||||||
expired: 'expired',
|
expired: 'expired',
|
||||||
},
|
},
|
||||||
|
system_config: {
|
||||||
|
base_config: 'Base Config',
|
||||||
|
base: {
|
||||||
|
url: 'Website URL',
|
||||||
|
url_tip: 'example:http://localhost:8081'
|
||||||
|
}
|
||||||
|
},
|
||||||
workspace: {
|
workspace: {
|
||||||
create: 'Create Workspace',
|
create: 'Create Workspace',
|
||||||
update: 'Update Workspace',
|
update: 'Update Workspace',
|
||||||
|
@ -461,6 +468,7 @@ export default {
|
||||||
input_url: "Please enter the request URL",
|
input_url: "Please enter the request URL",
|
||||||
input_path: "Please enter the request path",
|
input_path: "Please enter the request path",
|
||||||
name: "Name",
|
name: "Name",
|
||||||
|
content_type: "Content Type",
|
||||||
method: "Method",
|
method: "Method",
|
||||||
url: "URL",
|
url: "URL",
|
||||||
path: "Path",
|
path: "Path",
|
||||||
|
|
|
@ -175,6 +175,13 @@ export default {
|
||||||
invalid: '无效',
|
invalid: '无效',
|
||||||
expired: '已过期',
|
expired: '已过期',
|
||||||
},
|
},
|
||||||
|
system_config: {
|
||||||
|
base_config: '基本配置',
|
||||||
|
base: {
|
||||||
|
url: '当前站点URL',
|
||||||
|
url_tip: '例如:http://localhost:8081'
|
||||||
|
}
|
||||||
|
},
|
||||||
workspace: {
|
workspace: {
|
||||||
create: '创建工作空间',
|
create: '创建工作空间',
|
||||||
update: '修改工作空间',
|
update: '修改工作空间',
|
||||||
|
@ -461,6 +468,7 @@ export default {
|
||||||
input_url: "请输入请求URL",
|
input_url: "请输入请求URL",
|
||||||
input_path: "请输入请求路径",
|
input_path: "请输入请求路径",
|
||||||
name: "请求名称",
|
name: "请求名称",
|
||||||
|
content_type: "请求类型",
|
||||||
method: "请求方法",
|
method: "请求方法",
|
||||||
url: "请求URL",
|
url: "请求URL",
|
||||||
path: "请求路径",
|
path: "请求路径",
|
||||||
|
@ -730,6 +738,10 @@ export default {
|
||||||
plan_status_prepare: "未开始",
|
plan_status_prepare: "未开始",
|
||||||
plan_status_running: "进行中",
|
plan_status_running: "进行中",
|
||||||
plan_status_completed: "已完成",
|
plan_status_completed: "已完成",
|
||||||
|
planned_start_time: "计划开始",
|
||||||
|
planned_end_time: "计划结束",
|
||||||
|
actual_start_time: "实际开始",
|
||||||
|
actual_end_time: "实际结束",
|
||||||
plan_delete_confirm: "将删除该测试计划下所有用例,确认删除测试计划: ",
|
plan_delete_confirm: "将删除该测试计划下所有用例,确认删除测试计划: ",
|
||||||
plan_delete: "删除计划",
|
plan_delete: "删除计划",
|
||||||
},
|
},
|
||||||
|
|
|
@ -152,14 +152,14 @@ export default {
|
||||||
ge: "大於等於",
|
ge: "大於等於",
|
||||||
lt: "小於",
|
lt: "小於",
|
||||||
le: "小於等於",
|
le: "小於等於",
|
||||||
not_equals: "不等於",
|
|
||||||
equals: "等於",
|
equals: "等於",
|
||||||
|
not_equals: "不等於",
|
||||||
between: "之間",
|
between: "之間",
|
||||||
current_user: "是當前用戶"
|
current_user: "是當前用戶"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
license:{
|
license: {
|
||||||
title: '授權管理',
|
title: '授權管理',
|
||||||
corporation: '客戶名稱',
|
corporation: '客戶名稱',
|
||||||
time: '授權時間',
|
time: '授權時間',
|
||||||
|
@ -175,6 +175,13 @@ export default {
|
||||||
invalid: '無效',
|
invalid: '無效',
|
||||||
expired: '已過期',
|
expired: '已過期',
|
||||||
},
|
},
|
||||||
|
system_config: {
|
||||||
|
base_config: '基本配置',
|
||||||
|
base: {
|
||||||
|
url: '當前站點URL',
|
||||||
|
url_tip: '例如:http://localhost:8081'
|
||||||
|
}
|
||||||
|
},
|
||||||
workspace: {
|
workspace: {
|
||||||
create: '創建工作空間',
|
create: '創建工作空間',
|
||||||
update: '修改工作空間',
|
update: '修改工作空間',
|
||||||
|
@ -281,7 +288,7 @@ export default {
|
||||||
email_format_is_incorrect: '郵箱格式不正確',
|
email_format_is_incorrect: '郵箱格式不正確',
|
||||||
delete_confirm: '這個用戶確定要刪除嗎?',
|
delete_confirm: '這個用戶確定要刪除嗎?',
|
||||||
apikey_delete_confirm: '這個 API Key 確定要刪除嗎?',
|
apikey_delete_confirm: '這個 API Key 確定要刪除嗎?',
|
||||||
input_id_placeholder: '請輸入ID (不支持中文字符)',
|
input_id_placeholder: '請輸入ID (不支持中文)',
|
||||||
source: '用戶來源'
|
source: '用戶來源'
|
||||||
},
|
},
|
||||||
role: {
|
role: {
|
||||||
|
@ -463,6 +470,7 @@ export default {
|
||||||
name: "請求名稱",
|
name: "請求名稱",
|
||||||
method: "請求方法",
|
method: "請求方法",
|
||||||
url: "請求URL",
|
url: "請求URL",
|
||||||
|
content_type: "請求類型",
|
||||||
path: "請求路徑",
|
path: "請求路徑",
|
||||||
address: "請求地址",
|
address: "請求地址",
|
||||||
refer_to_environment: "引用環境",
|
refer_to_environment: "引用環境",
|
||||||
|
@ -632,7 +640,7 @@ export default {
|
||||||
cancel_relevance_success: "取消關聯成功",
|
cancel_relevance_success: "取消關聯成功",
|
||||||
switch_project: "切換項目",
|
switch_project: "切換項目",
|
||||||
case: {
|
case: {
|
||||||
export_all_cases: '確定要匯出全部用例嗎?',
|
export_all_cases: '確定要導出全部用例嗎?',
|
||||||
input_test_case: '請輸入關聯用例名稱',
|
input_test_case: '請輸入關聯用例名稱',
|
||||||
test_name: '測試名稱',
|
test_name: '測試名稱',
|
||||||
other: "--其他--",
|
other: "--其他--",
|
||||||
|
|
Loading…
Reference in New Issue