feat: 定时任务通知

This commit is contained in:
wenyann 2020-09-16 09:57:55 +08:00
parent 913ff44480
commit b221a51d4c
22 changed files with 341 additions and 170 deletions

View File

@ -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>

View File

@ -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) {

View File

@ -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;
} }

View File

@ -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,

View File

@ -0,0 +1,5 @@
package io.metersphere.base.mapper.ext;
public interface ExtSystemParameterMapper {
String email();
}

View File

@ -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>

View File

@ -16,4 +16,6 @@ public interface ExtUserMapper {
List<User> searchUser(String condition); List<User> searchUser(String condition);
List<String> queryEmails(String[] names);
} }

View File

@ -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">

View File

@ -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);
} }

View File

@ -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);
} }
} }

View File

@ -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();
}
} }
} }

View File

@ -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;
} }
} }

View File

@ -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();
} }

View File

@ -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();

View File

@ -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);
// //

View File

@ -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

View File

@ -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

View File

@ -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定时任务结果通知

View File

@ -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定時任務結果通知

View File

@ -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>

View File

@ -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>

View File

@ -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: "任务通知",