feat: 定时任务通知
This commit is contained in:
parent
913ff44480
commit
b221a51d4c
|
@ -296,6 +296,24 @@
|
||||||
<artifactId>commonmark</artifactId>
|
<artifactId>commonmark</artifactId>
|
||||||
<version>0.15.2</version>
|
<version>0.15.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains</groupId>
|
||||||
|
<artifactId>annotations</artifactId>
|
||||||
|
<version>1.1</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-test</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import io.metersphere.api.parse.JmeterDocumentParser;
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.ApiTestFileMapper;
|
import io.metersphere.base.mapper.ApiTestFileMapper;
|
||||||
import io.metersphere.base.mapper.ApiTestMapper;
|
import io.metersphere.base.mapper.ApiTestMapper;
|
||||||
|
import io.metersphere.base.mapper.UserMapper;
|
||||||
import io.metersphere.base.mapper.ext.ExtApiTestMapper;
|
import io.metersphere.base.mapper.ext.ExtApiTestMapper;
|
||||||
import io.metersphere.commons.constants.APITestStatus;
|
import io.metersphere.commons.constants.APITestStatus;
|
||||||
import io.metersphere.commons.constants.FileType;
|
import io.metersphere.commons.constants.FileType;
|
||||||
|
@ -23,9 +24,12 @@ import io.metersphere.controller.request.QueryScheduleRequest;
|
||||||
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.ApiTestJob;
|
import io.metersphere.job.sechedule.ApiTestJob;
|
||||||
|
import io.metersphere.notice.service.MailService;
|
||||||
|
import io.metersphere.notice.service.NoticeService;
|
||||||
import io.metersphere.service.FileService;
|
import io.metersphere.service.FileService;
|
||||||
import io.metersphere.service.QuotaService;
|
import io.metersphere.service.QuotaService;
|
||||||
import io.metersphere.service.ScheduleService;
|
import io.metersphere.service.ScheduleService;
|
||||||
|
import io.metersphere.service.UserService;
|
||||||
import io.metersphere.track.service.TestCaseService;
|
import io.metersphere.track.service.TestCaseService;
|
||||||
import org.apache.dubbo.common.URL;
|
import org.apache.dubbo.common.URL;
|
||||||
import org.apache.dubbo.common.constants.CommonConstants;
|
import org.apache.dubbo.common.constants.CommonConstants;
|
||||||
|
@ -44,7 +48,8 @@ import java.util.stream.Collectors;
|
||||||
@Service
|
@Service
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public class APITestService {
|
public class APITestService {
|
||||||
|
@Resource
|
||||||
|
private UserService userService;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiTestMapper apiTestMapper;
|
private ApiTestMapper apiTestMapper;
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -61,6 +66,10 @@ public class APITestService {
|
||||||
private ScheduleService scheduleService;
|
private ScheduleService scheduleService;
|
||||||
@Resource
|
@Resource
|
||||||
private TestCaseService testCaseService;
|
private TestCaseService testCaseService;
|
||||||
|
@Resource
|
||||||
|
private MailService mailService;
|
||||||
|
@Resource
|
||||||
|
private NoticeService noticeService;
|
||||||
|
|
||||||
private static final String BODY_FILE_DIR = "/opt/metersphere/data/body";
|
private static final String BODY_FILE_DIR = "/opt/metersphere/data/body";
|
||||||
|
|
||||||
|
@ -79,7 +88,7 @@ public class APITestService {
|
||||||
throw new IllegalArgumentException(Translator.get("file_cannot_be_null"));
|
throw new IllegalArgumentException(Translator.get("file_cannot_be_null"));
|
||||||
}
|
}
|
||||||
checkQuota();
|
checkQuota();
|
||||||
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds()) ;
|
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
||||||
request.setBodyUploadIds(null);
|
request.setBodyUploadIds(null);
|
||||||
ApiTest test = createTest(request);
|
ApiTest test = createTest(request);
|
||||||
createBodyFiles(test, bodyUploadIds, bodyFiles);
|
createBodyFiles(test, bodyUploadIds, bodyFiles);
|
||||||
|
@ -92,7 +101,7 @@ public class APITestService {
|
||||||
}
|
}
|
||||||
deleteFileByTestId(request.getId());
|
deleteFileByTestId(request.getId());
|
||||||
|
|
||||||
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds()) ;
|
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
||||||
request.setBodyUploadIds(null);
|
request.setBodyUploadIds(null);
|
||||||
ApiTest test = updateTest(request);
|
ApiTest test = updateTest(request);
|
||||||
createBodyFiles(test, bodyUploadIds, bodyFiles);
|
createBodyFiles(test, bodyUploadIds, bodyFiles);
|
||||||
|
@ -225,8 +234,11 @@ public class APITestService {
|
||||||
apiTest.setUserId(request.getUserId());
|
apiTest.setUserId(request.getUserId());
|
||||||
}
|
}
|
||||||
String reportId = apiReportService.create(apiTest, request.getTriggerMode());
|
String reportId = apiReportService.create(apiTest, request.getTriggerMode());
|
||||||
|
if (request.getTriggerMode().equals("SCHEDULE")) {
|
||||||
|
List<Notice> notice = noticeService.queryNotice(request.getId());
|
||||||
|
mailService.sendHtml(reportId,notice,"api");
|
||||||
|
}
|
||||||
changeStatus(request.getId(), APITestStatus.Running);
|
changeStatus(request.getId(), APITestStatus.Running);
|
||||||
|
|
||||||
jMeterService.run(request.getId(), null, is);
|
jMeterService.run(request.getId(), null, is);
|
||||||
return reportId;
|
return reportId;
|
||||||
}
|
}
|
||||||
|
@ -245,6 +257,7 @@ public class APITestService {
|
||||||
MSException.throwException(Translator.get("load_test_already_exists"));
|
MSException.throwException(Translator.get("load_test_already_exists"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkName(SaveAPITestRequest request) {
|
public void checkName(SaveAPITestRequest request) {
|
||||||
ApiTestExample example = new ApiTestExample();
|
ApiTestExample example = new ApiTestExample();
|
||||||
example.createCriteria().andNameEqualTo(request.getName()).andProjectIdEqualTo(request.getProjectId());
|
example.createCriteria().andNameEqualTo(request.getName()).andProjectIdEqualTo(request.getProjectId());
|
||||||
|
@ -411,7 +424,7 @@ public class APITestService {
|
||||||
}
|
}
|
||||||
updateTest(request);
|
updateTest(request);
|
||||||
APITestResult apiTest = get(request.getId());
|
APITestResult apiTest = get(request.getId());
|
||||||
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds()) ;
|
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
||||||
request.setBodyUploadIds(null);
|
request.setBodyUploadIds(null);
|
||||||
createBodyFiles(apiTest, bodyUploadIds, bodyFiles);
|
createBodyFiles(apiTest, bodyUploadIds, bodyFiles);
|
||||||
if (SessionUtils.getUser() == null) {
|
if (SessionUtils.getUser() == null) {
|
||||||
|
|
|
@ -15,5 +15,9 @@ 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;
|
||||||
}
|
}
|
|
@ -57,7 +57,16 @@
|
||||||
</include>
|
</include>
|
||||||
</if>
|
</if>
|
||||||
</sql>
|
</sql>
|
||||||
|
<select id="get" resultMap="BaseResultMap">
|
||||||
|
SELECT r.*, t.name AS test_name, project.name AS project_name, user.name AS user_name
|
||||||
|
FROM api_test_report r JOIN api_test t ON r.test_id = t.id
|
||||||
|
LEFT JOIN project ON project.id = t.project_id
|
||||||
|
LEFT JOIN user ON user.id = r.user_id
|
||||||
|
<where>
|
||||||
|
r.id = #{id}
|
||||||
|
</where>
|
||||||
|
ORDER BY r.update_time DESC
|
||||||
|
</select>
|
||||||
<select id="list" resultMap="BaseResultMap">
|
<select id="list" resultMap="BaseResultMap">
|
||||||
SELECT t.name AS test_name,
|
SELECT t.name AS test_name,
|
||||||
r.name, r.description, r.id, r.test_id, r.create_time, r.update_time, r.status, r.trigger_mode,
|
r.name, r.description, r.id, r.test_id, r.create_time, r.update_time, r.status, r.trigger_mode,
|
||||||
|
@ -125,16 +134,7 @@
|
||||||
ORDER BY r.update_time DESC
|
ORDER BY r.update_time DESC
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="get" resultMap="BaseResultMap">
|
|
||||||
SELECT r.*, t.name AS test_name, project.name AS project_name, user.name AS user_name
|
|
||||||
FROM api_test_report r JOIN api_test t ON r.test_id = t.id
|
|
||||||
LEFT JOIN project ON project.id = t.project_id
|
|
||||||
LEFT JOIN user ON user.id = r.user_id
|
|
||||||
<where>
|
|
||||||
r.id = #{id}
|
|
||||||
</where>
|
|
||||||
ORDER BY r.update_time DESC
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<select id="selectDashboardTests" resultType="io.metersphere.dto.DashboardTestDTO">
|
<select id="selectDashboardTests" resultType="io.metersphere.dto.DashboardTestDTO">
|
||||||
SELECT min(create_time) AS date, count(api_test_report.id) AS count,
|
SELECT min(create_time) AS date, count(api_test_report.id) AS count,
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package io.metersphere.base.mapper.ext;
|
||||||
|
|
||||||
|
public interface ExtSystemParameterMapper {
|
||||||
|
String email();
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?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.ext.ExtSystemParameterMapper">
|
||||||
|
|
||||||
|
<select id="email" resultType="string">
|
||||||
|
select param_value from system_parameter where param_key=#{smtp.account}
|
||||||
|
</select>
|
||||||
|
</mapper>
|
|
@ -16,4 +16,6 @@ public interface ExtUserMapper {
|
||||||
|
|
||||||
List<User> searchUser(String condition);
|
List<User> searchUser(String condition);
|
||||||
|
|
||||||
|
List<String> queryEmails(String[] names);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,18 @@
|
||||||
</where>
|
</where>
|
||||||
order by u.update_time desc
|
order by u.update_time desc
|
||||||
</select>
|
</select>
|
||||||
|
<!--查询邮箱-->
|
||||||
|
<select id="queryEmails" parameterType="java.lang.String" resultType="java.lang.String">
|
||||||
|
SELECT
|
||||||
|
email
|
||||||
|
from user
|
||||||
|
WHERE name IN
|
||||||
|
<foreach collection="array" item="id" index="index"
|
||||||
|
open="(" close=")" separator=",">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
|
||||||
|
</select>
|
||||||
|
|
||||||
<!--修改密码-->
|
<!--修改密码-->
|
||||||
<update id="updatePassword" parameterType="io.metersphere.base.domain.User">
|
<update id="updatePassword" parameterType="io.metersphere.base.domain.User">
|
||||||
|
|
|
@ -2,6 +2,7 @@ package io.metersphere.job.sechedule;
|
||||||
|
|
||||||
import io.metersphere.api.dto.SaveAPITestRequest;
|
import io.metersphere.api.dto.SaveAPITestRequest;
|
||||||
import io.metersphere.api.service.APITestService;
|
import io.metersphere.api.service.APITestService;
|
||||||
|
import io.metersphere.notice.service.MailService;
|
||||||
import io.metersphere.commons.constants.ReportTriggerMode;
|
import io.metersphere.commons.constants.ReportTriggerMode;
|
||||||
import io.metersphere.commons.constants.ScheduleGroup;
|
import io.metersphere.commons.constants.ScheduleGroup;
|
||||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
|
@ -13,7 +14,7 @@ import org.quartz.TriggerKey;
|
||||||
public class ApiTestJob extends MsScheduleJob {
|
public class ApiTestJob extends MsScheduleJob {
|
||||||
|
|
||||||
private APITestService apiTestService;
|
private APITestService apiTestService;
|
||||||
|
private MailService mailService;
|
||||||
public ApiTestJob() {
|
public ApiTestJob() {
|
||||||
apiTestService = (APITestService) CommonBeanFactory.getBean(APITestService.class);
|
apiTestService = (APITestService) CommonBeanFactory.getBean(APITestService.class);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package io.metersphere.notice.controller;
|
||||||
|
|
||||||
import io.metersphere.base.domain.Notice;
|
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.service.NoticeService;
|
import io.metersphere.notice.service.NoticeService;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@ -23,4 +24,5 @@ public class NoticeController {
|
||||||
public List<Notice> queryNotice(@PathVariable String testId) {
|
public List<Notice> queryNotice(@PathVariable String testId) {
|
||||||
return noticeService.queryNotice(testId);
|
return noticeService.queryNotice(testId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,138 @@
|
||||||
package io.metersphere.notice.service;
|
package io.metersphere.notice.service;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import io.metersphere.api.dto.APIReportResult;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import io.metersphere.api.service.APIReportService;
|
||||||
import org.springframework.mail.SimpleMailMessage;
|
import io.metersphere.base.domain.Notice;
|
||||||
import org.springframework.mail.javamail.JavaMailSender;
|
import io.metersphere.base.domain.SystemParameter;
|
||||||
|
import io.metersphere.commons.constants.ParamConstants;
|
||||||
|
import io.metersphere.commons.utils.EncryptUtils;
|
||||||
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
import io.metersphere.dto.LoadTestDTO;
|
||||||
|
import io.metersphere.performance.service.PerformanceTestService;
|
||||||
|
import io.metersphere.service.SystemParameterService;
|
||||||
|
import io.metersphere.service.UserService;
|
||||||
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
|
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||||
|
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.mail.MessagingException;
|
||||||
|
import javax.mail.internet.MimeMessage;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class MailService {
|
public class MailService {
|
||||||
/* @Autowired
|
@Resource
|
||||||
private JavaMailSender mailSender;
|
private APIReportService apiReportService;
|
||||||
@Value("${mail.fromMail.addr}")
|
@Resource
|
||||||
private String from;*/
|
private PerformanceTestService performanceTestService;
|
||||||
|
@Resource
|
||||||
|
private UserService userService;
|
||||||
|
@Resource
|
||||||
|
private SystemParameterService systemParameterService;
|
||||||
|
|
||||||
public void sendHtml(String id) {
|
public void sendHtml(String id, List<Notice> notice,String type) {
|
||||||
SimpleMailMessage message = new SimpleMailMessage();
|
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
|
||||||
/*
|
List<SystemParameter> paramList=systemParameterService.getParamList(ParamConstants.Classify.MAIL.getValue());
|
||||||
message.setFrom(from);
|
javaMailSender.setDefaultEncoding("UTF-8");
|
||||||
*/
|
javaMailSender.setProtocol("smtps");
|
||||||
message.setTo("15135125273@163.com");
|
for(SystemParameter p:paramList){
|
||||||
message.setSubject("测试报告");
|
if(p.getParamKey().equals("smtp.host")){
|
||||||
message.setText("全部通知");
|
javaMailSender.setHost(p.getParamValue());
|
||||||
/*try {
|
}
|
||||||
mailSender.send(message);
|
if(p.getParamKey().equals("smtp.port")){
|
||||||
} catch (Exception e) {
|
javaMailSender.setPort(Integer.parseInt(p.getParamValue()));
|
||||||
}*/
|
}
|
||||||
|
if(p.getParamKey().equals("smtp.account")){
|
||||||
|
javaMailSender.setUsername(p.getParamValue());
|
||||||
|
}
|
||||||
|
if(p.getParamKey().equals("smtp.password")){
|
||||||
|
javaMailSender.setPassword(EncryptUtils.aesDecrypt(p.getParamValue()).toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.put("mail.smtp.auth", "true");
|
||||||
|
props.put("mail.smtp.starttls.enable","true");
|
||||||
|
props.put("mail.smtp.starttls.required","true");
|
||||||
|
props.put("mail.smtp.timeout", "30000");
|
||||||
|
props.put("mail.smtp.connectiontimeout", "5000");
|
||||||
|
javaMailSender.setJavaMailProperties(props);
|
||||||
|
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
|
||||||
|
String testName="";
|
||||||
|
String state="";
|
||||||
|
if(type.equals("api")){
|
||||||
|
APIReportResult reportResult=apiReportService.get(id);
|
||||||
|
testName=reportResult.getTestName();
|
||||||
|
state=reportResult.getStatus();
|
||||||
|
}else if(type.equals("performance")){
|
||||||
|
LoadTestDTO performanceResult=performanceTestService.get(id);
|
||||||
|
testName=performanceResult.getName();
|
||||||
|
state=performanceResult.getStatus();
|
||||||
|
}
|
||||||
|
String html1="<!DOCTYPE html>\n" +
|
||||||
|
"<html lang=\"en\">\n" +
|
||||||
|
"<head>\n" +
|
||||||
|
" <meta charset=\"UTF-8\">\n" +
|
||||||
|
" <title>MeterSphere</title>\n" +
|
||||||
|
"</head>\n" +
|
||||||
|
"<body style=\"text-align: left\">\n" +
|
||||||
|
" <div>\n" +
|
||||||
|
" <h3>"+type+"定时任务结果通知</h3>\n" +
|
||||||
|
" <p> 尊敬的用户:您好,您所执行的"+testName+"运行失败,请点击报告链接查看</p>\n" +
|
||||||
|
" </div>\n" +
|
||||||
|
"</body>\n" +
|
||||||
|
"</html>";
|
||||||
|
String html2="<!DOCTYPE html>\n" +
|
||||||
|
"<html lang=\"en\">\n" +
|
||||||
|
"<head>\n" +
|
||||||
|
" <meta charset=\"UTF-8\">\n" +
|
||||||
|
" <title>MeterSphere</title>\n" +
|
||||||
|
"</head>\n" +
|
||||||
|
"<body style=\"text-align: left\">\n" +
|
||||||
|
" <div>\n" +
|
||||||
|
" <h3>"+type+"定时任务结果通知</h3>\n" +
|
||||||
|
" <p> 尊敬的用户:您好,"+testName+"运行成功,请点击报告链接查看</p>\n" +
|
||||||
|
" </div>\n" +
|
||||||
|
"</body>\n" +
|
||||||
|
"</html>";
|
||||||
|
try {
|
||||||
|
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
|
||||||
|
helper.setFrom(javaMailSender.getUsername());
|
||||||
|
helper.setSubject("MeterSphere定时任务结果通知");
|
||||||
|
String users[] = {};
|
||||||
|
List<String> successEmailList=new ArrayList<>();
|
||||||
|
List<String> failEmailList=new ArrayList<>();
|
||||||
|
if(notice.size()>0){
|
||||||
|
for(Notice n:notice){
|
||||||
|
if (n.getEnable().equals("true")&&n.getEvent().equals("执行成功")) {
|
||||||
|
successEmailList=userService.queryEmail(n.getNames());
|
||||||
|
}
|
||||||
|
if (n.getEnable().equals("true")&&n.getEvent().equals("执行失败")) {
|
||||||
|
failEmailList=userService.queryEmail(n.getNames());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
LogUtil.error("Recipient information is empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(state.equals("success")){
|
||||||
|
users=successEmailList.toArray(new String[successEmailList.size()]);
|
||||||
|
helper.setText(html2,true);
|
||||||
|
}else{
|
||||||
|
users=failEmailList.toArray(new String[failEmailList.size()]);
|
||||||
|
helper.setText(html1,true);
|
||||||
|
|
||||||
|
}
|
||||||
|
helper.setTo(users);
|
||||||
|
javaMailSender.send(mimeMessage);
|
||||||
|
|
||||||
|
} catch (MessagingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,14 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
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.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class NoticeService {
|
public class NoticeService {
|
||||||
@Resource
|
@Resource
|
||||||
private NoticeMapper noticeMapper;
|
private NoticeMapper noticeMapper;
|
||||||
|
|
||||||
public void saveNotice(NoticeRequest noticeRequest) {
|
public void saveNotice(NoticeRequest noticeRequest) {
|
||||||
NoticeExample example = new NoticeExample();
|
NoticeExample example = new NoticeExample();
|
||||||
example.createCriteria().andTestIdEqualTo(noticeRequest.getTestId());
|
example.createCriteria().andTestIdEqualTo(noticeRequest.getTestId());
|
||||||
|
@ -22,9 +23,14 @@ public class NoticeService {
|
||||||
if (notices != null) {
|
if (notices != null) {
|
||||||
noticeMapper.deleteByExample(example);
|
noticeMapper.deleteByExample(example);
|
||||||
noticeRequest.getNotices().forEach(notice -> {
|
noticeRequest.getNotices().forEach(notice -> {
|
||||||
notice.setEvent(noticeRequest.getEvent());
|
for(String x:notice.getNames()){
|
||||||
notice.setTestId(noticeRequest.getTestId());
|
notice.setEvent(notice.getEvent());
|
||||||
noticeMapper.insert(notice);
|
notice.setEmail(notice.getEmail());
|
||||||
|
notice.setEnable(notice.getEnable());
|
||||||
|
notice.setTestId(noticeRequest.getTestId());
|
||||||
|
notice.setName(x);
|
||||||
|
noticeMapper.insert(notice);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
noticeRequest.getNotices().forEach(notice -> {
|
noticeRequest.getNotices().forEach(notice -> {
|
||||||
|
@ -39,7 +45,39 @@ public class NoticeService {
|
||||||
public List<Notice> queryNotice(String id) {
|
public List<Notice> queryNotice(String id) {
|
||||||
NoticeExample example = new NoticeExample();
|
NoticeExample example = new NoticeExample();
|
||||||
example.createCriteria().andTestIdEqualTo(id);
|
example.createCriteria().andTestIdEqualTo(id);
|
||||||
return noticeMapper.selectByExample(example);
|
List<Notice> notices=noticeMapper.selectByExample(example);
|
||||||
|
List<Notice> notice=new ArrayList<>();
|
||||||
|
List<String> success=new ArrayList<>();
|
||||||
|
List<String> fail=new ArrayList<>();
|
||||||
|
String[] successArray=new String[success.size()];
|
||||||
|
String[] failArray=new String[fail.size()];
|
||||||
|
Notice notice1=new Notice();
|
||||||
|
Notice notice2=new Notice();
|
||||||
|
if(notices.size()>0){
|
||||||
|
for(Notice n:notices){
|
||||||
|
if(n.getEvent().equals("执行成功")){
|
||||||
|
success.add(n.getName());
|
||||||
|
notice1.setEnable(n.getEnable());
|
||||||
|
notice1.setTestId(id);
|
||||||
|
notice1.setEvent(n.getEvent());
|
||||||
|
notice1.setEmail(n.getEmail());
|
||||||
|
}
|
||||||
|
if(n.getEvent().equals("执行失败")){
|
||||||
|
fail.add(n.getName());
|
||||||
|
notice2.setEnable(n.getEnable());
|
||||||
|
notice2.setTestId(id);
|
||||||
|
notice2.setEvent(n.getEvent());
|
||||||
|
notice2.setEmail(n.getEmail());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
successArray=success.toArray(new String[success.size()]);
|
||||||
|
failArray=fail.toArray(new String[fail.size()]);
|
||||||
|
notice1.setNames(successArray);
|
||||||
|
notice2.setNames(failArray);
|
||||||
|
notice.add(notice1);
|
||||||
|
notice.add(notice2);
|
||||||
|
}
|
||||||
|
return notice;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ 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.service.MailService;
|
||||||
|
import io.metersphere.notice.service.NoticeService;
|
||||||
import io.metersphere.performance.engine.Engine;
|
import io.metersphere.performance.engine.Engine;
|
||||||
import io.metersphere.performance.engine.EngineFactory;
|
import io.metersphere.performance.engine.EngineFactory;
|
||||||
import io.metersphere.service.FileService;
|
import io.metersphere.service.FileService;
|
||||||
|
@ -80,6 +82,10 @@ public class PerformanceTestService {
|
||||||
private TestCaseMapper testCaseMapper;
|
private TestCaseMapper testCaseMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private TestCaseService testCaseService;
|
private TestCaseService testCaseService;
|
||||||
|
@Resource
|
||||||
|
private NoticeService noticeService;
|
||||||
|
@Resource
|
||||||
|
private MailService mailService;
|
||||||
|
|
||||||
public List<LoadTestDTO> list(QueryTestPlanRequest request) {
|
public List<LoadTestDTO> list(QueryTestPlanRequest request) {
|
||||||
request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders()));
|
request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders()));
|
||||||
|
@ -231,7 +237,10 @@ public class PerformanceTestService {
|
||||||
}
|
}
|
||||||
|
|
||||||
startEngine(loadTest, engine, request.getTriggerMode());
|
startEngine(loadTest, engine, request.getTriggerMode());
|
||||||
|
if (request.getTriggerMode().equals("SCHEDULE")) {
|
||||||
|
List<Notice> notice = noticeService.queryNotice(request.getId());
|
||||||
|
mailService.sendHtml(engine.getReportId(),notice,"performance");
|
||||||
|
}
|
||||||
return engine.getReportId();
|
return engine.getReportId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.service;
|
||||||
import io.metersphere.base.domain.SystemParameter;
|
import io.metersphere.base.domain.SystemParameter;
|
||||||
import io.metersphere.base.domain.SystemParameterExample;
|
import io.metersphere.base.domain.SystemParameterExample;
|
||||||
import io.metersphere.base.mapper.SystemParameterMapper;
|
import io.metersphere.base.mapper.SystemParameterMapper;
|
||||||
|
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;
|
||||||
|
@ -24,7 +25,12 @@ public class SystemParameterService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private SystemParameterMapper systemParameterMapper;
|
private SystemParameterMapper systemParameterMapper;
|
||||||
|
@Resource
|
||||||
|
private ExtSystemParameterMapper extSystemParameterMapper;
|
||||||
|
|
||||||
|
public String searchEmail(){
|
||||||
|
return extSystemParameterMapper.email();
|
||||||
|
}
|
||||||
public String getSystemLanguage() {
|
public String getSystemLanguage() {
|
||||||
String result = StringUtils.EMPTY;
|
String result = StringUtils.EMPTY;
|
||||||
SystemParameterExample example = new SystemParameterExample();
|
SystemParameterExample example = new SystemParameterExample();
|
||||||
|
|
|
@ -61,6 +61,9 @@ public class UserService {
|
||||||
@Resource
|
@Resource
|
||||||
private WorkspaceService workspaceService;
|
private WorkspaceService workspaceService;
|
||||||
|
|
||||||
|
public List<String> queryEmail(String[] names){
|
||||||
|
return extUserMapper.queryEmails(names);
|
||||||
|
}
|
||||||
public UserDTO insert(UserRequest user) {
|
public UserDTO insert(UserRequest user) {
|
||||||
checkUserParam(user);
|
checkUserParam(user);
|
||||||
//
|
//
|
||||||
|
|
|
@ -75,15 +75,7 @@ spring.servlet.multipart.max-request-size=500MB
|
||||||
# actuator
|
# actuator
|
||||||
management.server.port=8083
|
management.server.port=8083
|
||||||
management.endpoints.web.exposure.include=*
|
management.endpoints.web.exposure.include=*
|
||||||
spring.freemarker.checkTemplateLocation=false
|
#spring.freemarker.checkTemplateLocation=false
|
||||||
addr=2363807763@qq.com # 发邮件者
|
|
||||||
fromMail=
|
|
||||||
host=smtp.qq.com
|
|
||||||
mail=
|
|
||||||
password=uuwqrjbkzbfdeaha
|
|
||||||
port=9002
|
|
||||||
resources=
|
|
||||||
server=
|
|
||||||
spring=
|
|
||||||
static-locations=classpath:/resources/, classpath:/static/ ,classpath:/templates/
|
|
||||||
username=2363807763@qq.com
|
|
||||||
|
|
|
@ -150,4 +150,6 @@ quota_performance_excess_organization=The number of performance tests exceeds th
|
||||||
quota_max_threads_excess_workspace=The maximum number of concurrent threads exceeds the workspace quota
|
quota_max_threads_excess_workspace=The maximum number of concurrent threads exceeds the workspace quota
|
||||||
quota_max_threads_excess_organization=The maximum number of concurrent threads exceeds the organization quota
|
quota_max_threads_excess_organization=The maximum number of concurrent threads exceeds the organization quota
|
||||||
quota_duration_excess_workspace=The stress test duration exceeds the work space quota
|
quota_duration_excess_workspace=The stress test duration exceeds the work space quota
|
||||||
quota_duration_excess_organization=The stress test duration exceeds the organization quota
|
quota_duration_excess_organization=The stress test duration exceeds the organization quota
|
||||||
|
|
||||||
|
email_subject=Metersphere timing task result notification
|
|
@ -151,6 +151,7 @@ quota_max_threads_excess_workspace=最大并发数超过工作空间限额
|
||||||
quota_max_threads_excess_organization=最大并发数超过组织限额
|
quota_max_threads_excess_organization=最大并发数超过组织限额
|
||||||
quota_duration_excess_workspace=压测时长超过工作空间限额
|
quota_duration_excess_workspace=压测时长超过工作空间限额
|
||||||
quota_duration_excess_organization=压测时长超过组织限额
|
quota_duration_excess_organization=压测时长超过组织限额
|
||||||
|
email_subject=MeterSphere定时任务结果通知
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -150,4 +150,5 @@ quota_performance_excess_organization=性能測試數量超過組織限額
|
||||||
quota_max_threads_excess_workspace=最大並發數超過工作空間限額
|
quota_max_threads_excess_workspace=最大並發數超過工作空間限額
|
||||||
quota_max_threads_excess_organization=最大並發數超過組織限額
|
quota_max_threads_excess_organization=最大並發數超過組織限額
|
||||||
quota_duration_excess_workspace=壓測時長超過工作空間限額
|
quota_duration_excess_workspace=壓測時長超過工作空間限額
|
||||||
quota_duration_excess_organization=壓測時長超過組織限額
|
quota_duration_excess_organization=壓測時長超過組織限額
|
||||||
|
email_subject=MeterSphere定時任務結果通知
|
|
@ -4,6 +4,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||||
|
|
||||||
<el-tab-pane :label="$t('schedule.edit_timer_task')" name="first">
|
<el-tab-pane :label="$t('schedule.edit_timer_task')" name="first">
|
||||||
<el-form :model="form" :rules="rules" ref="from">
|
<el-form :model="form" :rules="rules" ref="from">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
|
@ -26,81 +27,50 @@
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="$t('schedule.task_notification')" name="second">
|
<el-tab-pane :label="$t('schedule.task_notification')" name="second">
|
||||||
<template>
|
<template>
|
||||||
<el-select v-model="eventType" :placeholder="$t('commons.please_select')">
|
|
||||||
<el-option
|
|
||||||
v-for="item in options"
|
|
||||||
:key="item.eventType"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.eventType">
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
<el-table
|
<el-table
|
||||||
:data="tableData"
|
:data="tableData"
|
||||||
style="width: 100%">
|
style="width: 100%">
|
||||||
|
<el-table-column
|
||||||
|
prop="event"
|
||||||
|
:label="$t('schedule.event')"
|
||||||
|
|
||||||
|
>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="name"
|
prop="name"
|
||||||
:label="$t('schedule.receiver')"
|
:label="$t('schedule.receiver')"
|
||||||
|
width="200"
|
||||||
>
|
>
|
||||||
<template v-slot:default="{row}">
|
<template v-slot:default="{row}">
|
||||||
<el-input
|
<el-select v-model="row.names" filterable multiple placeholder="请选择" @click.native="userList()">
|
||||||
size="mini"
|
<el-option
|
||||||
type="textarea"
|
v-for="item in options"
|
||||||
:rows="1"
|
:key="item.id"
|
||||||
class="edit-input"
|
:label="item.name"
|
||||||
v-model="row.name"
|
:value="item.name">
|
||||||
:placeholder="$t('schedule.receiver')"
|
</el-option>
|
||||||
clearable>
|
</el-select>
|
||||||
</el-input>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="email"
|
prop="email"
|
||||||
:label="$t('schedule.receiving_mode')"
|
:label="$t('schedule.receiving_mode')"
|
||||||
width="200"
|
>
|
||||||
>
|
|
||||||
<template v-slot:default="{row}">
|
|
||||||
<el-input
|
|
||||||
size="mini"
|
|
||||||
type="textarea"
|
|
||||||
:rows="1"
|
|
||||||
class="edit-input"
|
|
||||||
v-model="row.email"
|
|
||||||
:placeholder="$t('schedule.input_email')"
|
|
||||||
clearable>
|
|
||||||
</el-input>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
:label="$t('test_resource_pool.enable_disable')"
|
:label="$t('test_resource_pool.enable_disable')"
|
||||||
prop="enable"
|
prop="enable"
|
||||||
>
|
>
|
||||||
<template v-slot:default="{row}">
|
<template v-slot:default="{row}">
|
||||||
<el-switch
|
<el-switch
|
||||||
v-model="row.enable"
|
v-model="row.enable"
|
||||||
active-value="true"
|
active-value="true"
|
||||||
inactive-value="false"
|
inactive-value="false"
|
||||||
inactive-color="#ff4949"
|
inactive-color="#ff4949"
|
||||||
@change="stateChange(row)"
|
|
||||||
/>
|
/>
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column :label="$t('schedule.operation')">
|
|
||||||
<template v-slot:default="scope">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
icon="el-icon-plus"
|
|
||||||
circle size="mini"
|
|
||||||
@click="handleAddStep(scope.$index)"></el-button>
|
|
||||||
<el-button
|
|
||||||
:disabled="(scope.$index == 0 && tableData.length <= 1)"
|
|
||||||
type="danger"
|
|
||||||
icon="el-icon-delete"
|
|
||||||
circle size="mini"
|
|
||||||
@click="handleDeleteStep(scope.$index)"></el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<el-button type="primary" @click="saveNotice">{{$t('commons.save')}}</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
@ -111,20 +81,20 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import Crontab from "../cron/Crontab";
|
import Crontab from "../cron/Crontab";
|
||||||
import CrontabResult from "../cron/CrontabResult";
|
import CrontabResult from "../cron/CrontabResult";
|
||||||
import {cronValidate} from "@/common/js/cron";
|
import {cronValidate} from "@/common/js/cron";
|
||||||
import {listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
import {listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||||
|
|
||||||
function defaultCustomValidate() {
|
function defaultCustomValidate() {
|
||||||
return {pass: true};
|
return {pass: true};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsScheduleEdit",
|
name: "MsScheduleEdit",
|
||||||
components: {CrontabResult, Crontab},
|
components: {CrontabResult, Crontab},
|
||||||
props: {
|
props: {
|
||||||
testId:String,
|
testId: String,
|
||||||
save: Function,
|
save: Function,
|
||||||
schedule: {},
|
schedule: {},
|
||||||
customValidate: {
|
customValidate: {
|
||||||
|
@ -167,25 +137,22 @@ function defaultCustomValidate() {
|
||||||
form: {
|
form: {
|
||||||
cronValue: ""
|
cronValue: ""
|
||||||
},
|
},
|
||||||
options: [{
|
|
||||||
eventType: 'success',
|
|
||||||
label: '执行成功通知'
|
|
||||||
}, {
|
|
||||||
eventType: 'fail',
|
|
||||||
label: '执行失败通知'
|
|
||||||
}, {
|
|
||||||
eventType: 'all',
|
|
||||||
label: '全部通知'
|
|
||||||
}],
|
|
||||||
eventType: '',
|
|
||||||
tableData: [
|
tableData: [
|
||||||
{
|
{
|
||||||
name: "",
|
event: "执行成功",
|
||||||
email: "",
|
names: [],
|
||||||
enable:true
|
email: "邮箱",
|
||||||
|
enable: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event: "执行失败",
|
||||||
|
names: [],
|
||||||
|
email: "邮箱",
|
||||||
|
enable: false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
enable:true,
|
options: [{}],
|
||||||
|
enable: true,
|
||||||
email: "",
|
email: "",
|
||||||
activeName: 'first',
|
activeName: 'first',
|
||||||
rules: {
|
rules: {
|
||||||
|
@ -194,56 +161,31 @@ function defaultCustomValidate() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
stateChange(s){
|
userList() {
|
||||||
alert(s.enable)
|
this.result = this.$get('user/list', response => {
|
||||||
this.result=this.$get('notice/editState/'+s.email,response=>{
|
this.options = response.data
|
||||||
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleClick() {
|
handleClick() {
|
||||||
if(this.activeName=="second"){
|
if (this.activeName == "second") {
|
||||||
this.result=this.$get('notice/query/'+this.testId,response=>{
|
this.result = this.$get('notice/query/' + this.testId, response => {
|
||||||
if(response.data.length<=0){
|
if (response.data.length > 0) {
|
||||||
this.tableData.email=""
|
this.tableData = response.data
|
||||||
this.tableData.name=""
|
|
||||||
this.tableData.enable=true
|
|
||||||
}else{
|
|
||||||
this.tableData=response.data
|
|
||||||
response.data.forEach(t=>{
|
|
||||||
this.eventType=t.event
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
saveNotice(){
|
|
||||||
let param = this.buildParam();
|
|
||||||
this.result=this.$post("notice/save",param,()=>{
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
},
|
|
||||||
buildParam() {
|
buildParam() {
|
||||||
let param = {};
|
let param = {};
|
||||||
param.notices = this.tableData
|
param.notices = this.tableData
|
||||||
param.testId = this.testId
|
param.testId = this.testId
|
||||||
param.event = this.eventType
|
|
||||||
return param;
|
return param;
|
||||||
},
|
},
|
||||||
handleAddStep(index) {
|
|
||||||
let form = {}
|
|
||||||
form.name = null;
|
|
||||||
form.email = null;
|
|
||||||
form.enable = null
|
|
||||||
this.tableData.splice(index + 1, 0, form);
|
|
||||||
},
|
|
||||||
handleDeleteStep(index) {
|
|
||||||
this.tableData.splice(index, 1);
|
|
||||||
},
|
|
||||||
open() {
|
open() {
|
||||||
this.dialogVisible = true;
|
this.dialogVisible = true;
|
||||||
this.form.cronValue = this.schedule.value;
|
this.form.cronValue = this.schedule.value;
|
||||||
listenGoBack(this.close);
|
listenGoBack(this.close);
|
||||||
|
this.handleClick()
|
||||||
},
|
},
|
||||||
crontabFill(value, resultList) {
|
crontabFill(value, resultList) {
|
||||||
//确定后回传的值
|
//确定后回传的值
|
||||||
|
@ -264,6 +206,10 @@ function defaultCustomValidate() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
let param = this.buildParam();
|
||||||
|
this.result = this.$post("notice/save", param, () => {
|
||||||
|
|
||||||
|
})
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
this.dialogVisible = false;
|
this.dialogVisible = false;
|
||||||
|
@ -296,13 +242,13 @@ function defaultCustomValidate() {
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
||||||
.inp {
|
.inp {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-form-item {
|
.el-form-item {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
<ms-schedule-config :schedule="testPlan.schedule" :save="saveCronExpression" @scheduleChange="saveSchedule"
|
<ms-schedule-config :schedule="testPlan.schedule" :save="saveCronExpression" @scheduleChange="saveSchedule"
|
||||||
:check-open="checkScheduleEdit" :custom-validate="durationValidate"/>
|
:check-open="checkScheduleEdit" :test-id="testId" :custom-validate="durationValidate"/>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
|
|
@ -821,7 +821,7 @@ export default {
|
||||||
schedule: {
|
schedule: {
|
||||||
input_email: "请输入邮箱账号",
|
input_email: "请输入邮箱账号",
|
||||||
event: "事件",
|
event: "事件",
|
||||||
receiving_mode: "邮箱",
|
receiving_mode: "接收方式",
|
||||||
receiver: "接收人",
|
receiver: "接收人",
|
||||||
operation: "操作",
|
operation: "操作",
|
||||||
task_notification: "任务通知",
|
task_notification: "任务通知",
|
||||||
|
|
Loading…
Reference in New Issue