Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
MeterSphere
metersphere
提交
4552b58b
M
metersphere
项目概览
MeterSphere
/
metersphere
上一次同步 3 年多
通知
25
Star
1
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
metersphere
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
4552b58b
编写于
12月 22, 2020
作者:
S
song.tianyang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat(接口自动化): 增加定时任务功能
为场景增加定时任务功能,功能位置放于场景表格每一行都"操作"处
上级
ae647f79
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
648 addition
and
17 deletion
+648
-17
backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java
...o/metersphere/api/controller/ApiAutomationController.java
+18
-0
backend/src/main/java/io/metersphere/api/dto/automation/RunScenarioRequest.java
...io/metersphere/api/dto/automation/RunScenarioRequest.java
+2
-0
backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java
...java/io/metersphere/api/service/ApiAutomationService.java
+46
-11
backend/src/main/java/io/metersphere/commons/constants/ScheduleGroup.java
.../java/io/metersphere/commons/constants/ScheduleGroup.java
+1
-1
backend/src/main/java/io/metersphere/job/sechedule/ApiScenarioTestJob.java
...java/io/metersphere/job/sechedule/ApiScenarioTestJob.java
+74
-0
backend/src/main/java/io/metersphere/job/sechedule/ApiTestJob.java
...rc/main/java/io/metersphere/job/sechedule/ApiTestJob.java
+1
-1
backend/src/main/java/io/metersphere/job/sechedule/ScheduleManager.java
...in/java/io/metersphere/job/sechedule/ScheduleManager.java
+5
-0
backend/src/main/java/io/metersphere/service/ScheduleService.java
...src/main/java/io/metersphere/service/ScheduleService.java
+2
-0
frontend/src/business/components/api/automation/scenario/ScenarioExtendBtns.vue
...components/api/automation/scenario/ScenarioExtendBtns.vue
+4
-4
frontend/src/business/components/api/automation/schedule/ScheduleMaintain.vue
...s/components/api/automation/schedule/ScheduleMaintain.vue
+244
-0
frontend/src/business/components/api/automation/schedule/ScheduleNotification.vue
...mponents/api/automation/schedule/ScheduleNotification.vue
+251
-0
未找到文件。
backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java
浏览文件 @
4552b58b
...
...
@@ -2,15 +2,21 @@ package io.metersphere.api.controller;
import
com.github.pagehelper.Page
;
import
com.github.pagehelper.PageHelper
;
import
io.metersphere.api.dto.APITestResult
;
import
io.metersphere.api.dto.automation.*
;
import
io.metersphere.api.dto.definition.RunDefinitionRequest
;
import
io.metersphere.api.service.ApiAutomationService
;
import
io.metersphere.base.domain.ApiScenario
;
import
io.metersphere.base.domain.ApiScenarioWithBLOBs
;
import
io.metersphere.base.domain.ApiTest
;
import
io.metersphere.base.domain.Schedule
;
import
io.metersphere.commons.constants.RoleConstants
;
import
io.metersphere.commons.constants.ScheduleGroup
;
import
io.metersphere.commons.utils.BeanUtils
;
import
io.metersphere.commons.utils.PageUtils
;
import
io.metersphere.commons.utils.Pager
;
import
io.metersphere.commons.utils.SessionUtils
;
import
io.metersphere.service.ScheduleService
;
import
org.apache.shiro.authz.annotation.Logical
;
import
org.apache.shiro.authz.annotation.RequiresRoles
;
import
org.springframework.web.bind.annotation.*
;
...
...
@@ -27,6 +33,7 @@ public class ApiAutomationController {
@Resource
ApiAutomationService
apiAutomationService
;
@PostMapping
(
"/list/{goPage}/{pageSize}"
)
public
Pager
<
List
<
ApiScenarioDTO
>>
list
(
@PathVariable
int
goPage
,
@PathVariable
int
pageSize
,
@RequestBody
ApiScenarioRequest
request
)
{
Page
<
Object
>
page
=
PageHelper
.
startPage
(
goPage
,
pageSize
,
true
);
...
...
@@ -96,5 +103,16 @@ public class ApiAutomationController {
return
apiAutomationService
.
addScenarioToPlan
(
request
);
}
@PostMapping
(
value
=
"/schedule/update"
)
public
void
updateSchedule
(
@RequestBody
Schedule
request
)
{
apiAutomationService
.
updateSchedule
(
request
);
}
@PostMapping
(
value
=
"/schedule/create"
)
public
void
createSchedule
(
@RequestBody
Schedule
request
)
{
apiAutomationService
.
createSchedule
(
request
);
}
}
backend/src/main/java/io/metersphere/api/dto/automation/RunScenarioRequest.java
浏览文件 @
4552b58b
...
...
@@ -21,5 +21,7 @@ public class RunScenarioRequest {
private
String
executeType
;
private
String
reportUserID
;
private
List
<
String
>
scenarioIds
;
}
backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java
浏览文件 @
4552b58b
...
...
@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
import
com.fasterxml.jackson.core.type.TypeReference
;
import
com.fasterxml.jackson.databind.DeserializationFeature
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.google.gson.Gson
;
import
io.metersphere.api.dto.automation.*
;
import
io.metersphere.api.dto.datacount.ApiDataCountResult
;
import
io.metersphere.api.dto.definition.RunDefinitionRequest
;
...
...
@@ -12,21 +13,19 @@ import io.metersphere.api.dto.definition.request.*;
import
io.metersphere.api.dto.scenario.KeyValue
;
import
io.metersphere.api.dto.scenario.environment.EnvironmentConfig
;
import
io.metersphere.api.jmeter.JMeterService
;
import
io.metersphere.base.domain.ApiScenario
;
import
io.metersphere.base.domain.ApiScenarioExample
;
import
io.metersphere.base.domain.ApiScenarioWithBLOBs
;
import
io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs
;
import
io.metersphere.base.domain.*
;
import
io.metersphere.base.mapper.ApiScenarioMapper
;
import
io.metersphere.base.mapper.ext.ExtApiScenarioMapper
;
import
io.metersphere.base.mapper.ext.ExtTestPlanMapper
;
import
io.metersphere.commons.constants.APITestStatus
;
import
io.metersphere.commons.constants.ApiRunMode
;
import
io.metersphere.commons.constants.ReportTriggerMode
;
import
io.metersphere.commons.constants.*
;
import
io.metersphere.commons.exception.MSException
;
import
io.metersphere.commons.utils.DateUtils
;
import
io.metersphere.commons.utils.ServiceUtils
;
import
io.metersphere.commons.utils.SessionUtils
;
import
io.metersphere.i18n.Translator
;
import
io.metersphere.job.sechedule.ApiScenarioTestJob
;
import
io.metersphere.job.sechedule.ApiTestJob
;
import
io.metersphere.service.ScheduleService
;
import
io.metersphere.track.dto.TestPlanDTO
;
import
io.metersphere.track.request.testcase.QueryTestPlanRequest
;
import
org.apache.commons.collections.CollectionUtils
;
...
...
@@ -54,11 +53,15 @@ public class ApiAutomationService {
private
ApiDefinitionService
apiDefinitionService
;
@Resource
private
ExtApiScenarioMapper
extApiScenarioMapper
;
// @Resource
// private ApiTagMapper apiTagMapper;
@Resource
private
JMeterService
jMeterService
;
@Resource
private
ApiTestEnvironmentService
environmentService
;
@Resource
private
ScheduleService
scheduleService
;
@Resource
private
ApiScenarioReportService
apiReportService
;
@Resource
private
ExtTestPlanMapper
extTestPlanMapper
;
...
...
@@ -184,14 +187,19 @@ public class ApiAutomationService {
return
new
ArrayList
<>();
}
private
void
createAPIScenarioReportResult
(
String
id
,
String
triggerMode
,
String
execType
,
String
projectId
)
{
private
void
createAPIScenarioReportResult
(
String
id
,
String
triggerMode
,
String
execType
,
String
projectId
,
String
userID
)
{
APIScenarioReportResult
report
=
new
APIScenarioReportResult
();
report
.
setId
(
id
);
report
.
setName
(
"测试执行结果"
);
report
.
setCreateTime
(
System
.
currentTimeMillis
());
report
.
setUpdateTime
(
System
.
currentTimeMillis
());
report
.
setStatus
(
APITestStatus
.
Running
.
name
());
report
.
setUserId
(
SessionUtils
.
getUserId
());
if
(
StringUtils
.
isNotEmpty
(
userID
)){
report
.
setUserId
(
userID
);
}
else
{
report
.
setUserId
(
SessionUtils
.
getUserId
());
}
report
.
setTriggerMode
(
triggerMode
);
report
.
setExecuteType
(
execType
);
report
.
setProjectId
(
projectId
);
...
...
@@ -210,10 +218,12 @@ public class ApiAutomationService {
MsTestPlan
testPlan
=
new
MsTestPlan
();
testPlan
.
setHashTree
(
new
LinkedList
<>());
HashTree
jmeterTestPlanHashTree
=
new
ListedHashTree
();
String
projectID
=
request
.
getProjectId
();
for
(
ApiScenarioWithBLOBs
item
:
apiScenarios
)
{
MsThreadGroup
group
=
new
MsThreadGroup
();
group
.
setLabel
(
item
.
getName
());
group
.
setName
(
item
.
getName
());
projectID
=
item
.
getProjectId
();
try
{
ObjectMapper
mapper
=
new
ObjectMapper
();
mapper
.
configure
(
DeserializationFeature
.
FAIL_ON_UNKNOWN_PROPERTIES
,
false
);
...
...
@@ -245,7 +255,7 @@ public class ApiAutomationService {
jMeterService
.
runDefinition
(
request
.
getId
(),
jmeterTestPlanHashTree
,
request
.
getReportId
(),
ApiRunMode
.
SCENARIO
.
name
());
createAPIScenarioReportResult
(
request
.
getId
(),
request
.
getTriggerMode
()
==
null
?
ReportTriggerMode
.
MANUAL
.
name
()
:
request
.
getTriggerMode
(),
request
.
getExecuteType
(),
request
.
getProjectId
());
request
.
getExecuteType
(),
projectID
,
request
.
getReportUserID
());
return
request
.
getId
();
}
...
...
@@ -271,7 +281,8 @@ public class ApiAutomationService {
request
.
getTestElement
().
getJmx
(
hashTree
);
// 调用执行方法
jMeterService
.
runDefinition
(
request
.
getId
(),
hashTree
,
request
.
getReportId
(),
ApiRunMode
.
SCENARIO
.
name
());
createAPIScenarioReportResult
(
request
.
getId
(),
ReportTriggerMode
.
MANUAL
.
name
(),
request
.
getExecuteType
(),
request
.
getProjectId
());
createAPIScenarioReportResult
(
request
.
getId
(),
ReportTriggerMode
.
MANUAL
.
name
(),
request
.
getExecuteType
(),
request
.
getProjectId
(),
SessionUtils
.
getUserId
());
return
request
.
getId
();
}
...
...
@@ -347,4 +358,28 @@ public class ApiAutomationService {
public
List
<
ApiDataCountResult
>
countRunResultByProjectID
(
String
projectId
)
{
return
extApiScenarioMapper
.
countRunResultByProjectID
(
projectId
);
}
public
void
createSchedule
(
Schedule
request
)
{
Schedule
schedule
=
scheduleService
.
buildApiTestSchedule
(
request
);
schedule
.
setJob
(
ApiScenarioTestJob
.
class
.
getName
());
schedule
.
setGroup
(
ScheduleGroup
.
API_SCENARIO_TEST
.
name
());
schedule
.
setType
(
ScheduleType
.
CRON
.
name
());
scheduleService
.
addSchedule
(
schedule
);
this
.
addOrUpdateApiScenarioCronJob
(
request
);
}
public
void
updateSchedule
(
Schedule
request
)
{
scheduleService
.
editSchedule
(
request
);
this
.
addOrUpdateApiScenarioCronJob
(
request
);
}
private
void
addOrUpdateApiScenarioCronJob
(
Schedule
request
)
{
scheduleService
.
addOrUpdateCronJob
(
request
,
ApiScenarioTestJob
.
getJobKey
(
request
.
getResourceId
()),
ApiScenarioTestJob
.
getTriggerKey
(
request
.
getResourceId
()),
ApiScenarioTestJob
.
class
);
}
}
backend/src/main/java/io/metersphere/commons/constants/ScheduleGroup.java
浏览文件 @
4552b58b
package
io.metersphere.commons.constants
;
public
enum
ScheduleGroup
{
API_TEST
,
PERFORMANCE_TEST
API_TEST
,
PERFORMANCE_TEST
,
API_SCENARIO_TEST
}
backend/src/main/java/io/metersphere/job/sechedule/ApiScenarioTestJob.java
0 → 100644
浏览文件 @
4552b58b
package
io.metersphere.job.sechedule
;
import
io.metersphere.api.dto.SaveAPITestRequest
;
import
io.metersphere.api.dto.automation.ExecuteType
;
import
io.metersphere.api.dto.automation.RunScenarioRequest
;
import
io.metersphere.api.service.APITestService
;
import
io.metersphere.api.service.ApiAutomationService
;
import
io.metersphere.commons.constants.ReportTriggerMode
;
import
io.metersphere.commons.constants.ScheduleGroup
;
import
io.metersphere.commons.utils.CommonBeanFactory
;
import
io.metersphere.commons.utils.LogUtil
;
import
org.quartz.*
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.UUID
;
/**
* 情景测试Job
* @author song.tianyang
* @Date 2020/12/22 2:59 下午
* @Description
*/
public
class
ApiScenarioTestJob
extends
MsScheduleJob
{
private
String
projectID
;
private
List
<
String
>
scenarioIds
;
private
ApiAutomationService
apiAutomationService
;
public
ApiScenarioTestJob
()
{
apiAutomationService
=
(
ApiAutomationService
)
CommonBeanFactory
.
getBean
(
ApiAutomationService
.
class
);
}
@Override
public
void
execute
(
JobExecutionContext
context
)
throws
JobExecutionException
{
JobKey
jobKey
=
context
.
getTrigger
().
getJobKey
();
JobDataMap
jobDataMap
=
context
.
getJobDetail
().
getJobDataMap
();
String
resourceId
=
jobDataMap
.
getString
(
"resourceId"
);
this
.
userId
=
jobDataMap
.
getString
(
"userId"
);
this
.
expression
=
jobDataMap
.
getString
(
"expression"
);
this
.
projectID
=
jobDataMap
.
getString
(
"projectId"
);
if
(
resourceId
!=
null
){
scenarioIds
=
new
ArrayList
<>();
scenarioIds
.
add
(
resourceId
);
}
LogUtil
.
info
(
jobKey
.
getGroup
()
+
" Running: "
+
resourceId
);
LogUtil
.
info
(
"CronExpression: "
+
expression
);
businessExecute
(
context
);
}
@Override
void
businessExecute
(
JobExecutionContext
context
)
{
RunScenarioRequest
request
=
new
RunScenarioRequest
();
String
id
=
UUID
.
randomUUID
().
toString
();
request
.
setId
(
id
);
request
.
setReportId
(
id
);
request
.
setProjectId
(
projectID
);
request
.
setTriggerMode
(
ReportTriggerMode
.
MANUAL
.
name
());
request
.
setExecuteType
(
ExecuteType
.
Completed
.
name
());
request
.
setScenarioIds
(
this
.
scenarioIds
);
request
.
setReportUserID
(
this
.
userId
);
apiAutomationService
.
run
(
request
);
}
public
static
JobKey
getJobKey
(
String
testId
)
{
return
new
JobKey
(
testId
,
ScheduleGroup
.
API_SCENARIO_TEST
.
name
());
}
public
static
TriggerKey
getTriggerKey
(
String
testId
)
{
return
new
TriggerKey
(
testId
,
ScheduleGroup
.
API_SCENARIO_TEST
.
name
());
}
}
backend/src/main/java/io/metersphere/job/sechedule/ApiTestJob.java
浏览文件 @
4552b58b
...
...
@@ -9,7 +9,6 @@ import org.quartz.JobExecutionContext;
import
org.quartz.JobKey
;
import
org.quartz.TriggerKey
;
public
class
ApiTestJob
extends
MsScheduleJob
{
private
APITestService
apiTestService
;
...
...
@@ -34,3 +33,4 @@ public class ApiTestJob extends MsScheduleJob {
return
new
TriggerKey
(
testId
,
ScheduleGroup
.
API_TEST
.
name
());
}
}
backend/src/main/java/io/metersphere/job/sechedule/ScheduleManager.java
浏览文件 @
4552b58b
package
io.metersphere.job.sechedule
;
import
io.metersphere.commons.constants.ScheduleGroup
;
import
io.metersphere.commons.utils.LogUtil
;
import
org.python.antlr.ast.Str
;
import
org.quartz.*
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.Resource
;
import
java.util.List
;
import
java.util.Set
;
@Component
public
class
ScheduleManager
{
...
...
@@ -291,4 +295,5 @@ public class ScheduleManager {
jobDataMap
.
put
(
"userId"
,
userId
);
return
jobDataMap
;
}
}
backend/src/main/java/io/metersphere/service/ScheduleService.java
浏览文件 @
4552b58b
...
...
@@ -20,6 +20,7 @@ import io.metersphere.dto.ScheduleDao;
import
io.metersphere.job.sechedule.ApiTestJob
;
import
io.metersphere.job.sechedule.ScheduleManager
;
import
org.apache.commons.lang3.StringUtils
;
import
org.quartz.JobDetail
;
import
org.quartz.JobKey
;
import
org.quartz.SchedulerException
;
import
org.quartz.TriggerKey
;
...
...
@@ -64,6 +65,7 @@ public class ScheduleService {
}
public
Schedule
getScheduleByResource
(
String
resourceId
,
String
group
)
{
ScheduleExample
example
=
new
ScheduleExample
();
example
.
createCriteria
().
andResourceIdEqualTo
(
resourceId
).
andGroupEqualTo
(
group
);
List
<
Schedule
>
schedules
=
scheduleMapper
.
selectByExample
(
example
);
...
...
frontend/src/business/components/api/automation/scenario/ScenarioExtendBtns.vue
浏览文件 @
4552b58b
...
...
@@ -5,20 +5,20 @@
</el-link>
<el-dropdown-menu
slot=
"dropdown"
>
<el-dropdown-item
command=
"ref"
>
{{
$t
(
'
api_test.automation.view_ref
'
)
}}
</el-dropdown-item>
<!--
<el-dropdown-item
command=
"schedule"
>
{{
$t
(
'
api_test.automation.schedule
'
)
}}
</el-dropdown-item>
--
>
<el-dropdown-item
command=
"schedule"
>
{{
$t
(
'
api_test.automation.schedule
'
)
}}
</el-dropdown-item
>
</el-dropdown-menu>
<ms-reference-view
ref=
"viewRef"
/>
<!--
<ms-schedule-maintain
ref=
"scheduleMaintain"
/>
--
>
<ms-schedule-maintain
ref=
"scheduleMaintain"
/
>
</el-dropdown>
</
template
>
<
script
>
import
MsReferenceView
from
"
@/business/components/api/automation/scenario/ReferenceView
"
;
//
import MsScheduleMaintain from "@/business/components/api/automation/schedule/ScheduleMaintain"
import
MsScheduleMaintain
from
"
@/business/components/api/automation/schedule/ScheduleMaintain
"
export
default
{
name
:
"
MsScenarioExtendButtons
"
,
components
:
{
MsReferenceView
},
components
:
{
MsReferenceView
,
MsScheduleMaintain
},
props
:
{
row
:
Object
},
...
...
frontend/src/business/components/api/automation/schedule/ScheduleMaintain.vue
0 → 100644
浏览文件 @
4552b58b
<
template
>
<el-dialog
:close-on-click-modal=
"false"
width=
"60%"
class=
"schedule-edit"
:visible.sync=
"dialogVisible"
@
close=
"close"
>
<template>
<div>
<el-tabs
v-model=
"activeName"
>
<el-tab-pane
:label=
"$t('schedule.edit_timer_task')"
name=
"first"
>
<el-form
:model=
"form"
:rules=
"rules"
ref=
"from"
>
<el-form-item
prop=
"cronValue"
>
<el-input
:disabled=
"isReadOnly"
v-model=
"form.cronValue"
class=
"inp"
:placeholder=
"$t('schedule.please_input_cron_expression')"
/>
<el-button
:disabled=
"isReadOnly"
type=
"primary"
@
click=
"saveCron"
>
{{
$t
(
'
commons.save
'
)
}}
</el-button>
</el-form-item>
<el-form-item>
<el-link
:disabled=
"isReadOnly"
type=
"primary"
@
click=
"showCronDialog"
>
{{
$t
(
'
schedule.generate_expression
'
)
}}
</el-link>
</el-form-item>
<crontab-result
:ex=
"form.cronValue"
ref=
"crontabResult"
/>
</el-form>
<el-dialog
width=
"60%"
:title=
"$t('schedule.generate_expression')"
:visible.sync=
"showCron"
:modal=
"false"
>
<crontab
@
hide=
"showCron=false"
@
fill=
"crontabFill"
:expression=
"schedule.value"
ref=
"crontab"
/>
</el-dialog>
</el-tab-pane>
<el-tab-pane
:label=
"$t('schedule.task_notification')"
name=
"second"
>
<ms-schedule-notification
:is-tester-permission=
"isTesterPermission"
:test-id=
"testId"
:schedule-receiver-options=
"scheduleReceiverOptions"
/>
</el-tab-pane>
</el-tabs>
</div>
</
template
>
</el-dialog>
</template>
<
script
>
import
{
checkoutTestManagerOrTestUser
,
getCurrentUser
,
listenGoBack
,
removeGoBackListener
}
from
"
@/common/js/utils
"
;
import
Crontab
from
"
@/business/components/common/cron/Crontab
"
;
import
CrontabResult
from
"
@/business/components/common/cron/CrontabResult
"
;
import
{
cronValidate
}
from
"
@/common/js/cron
"
;
import
MsScheduleNotification
from
"
./ScheduleNotification
"
;
function
defaultCustomValidate
()
{
return
{
pass
:
true
};
}
const
requireComponent
=
require
.
context
(
'
@/business/components/xpack/
'
,
true
,
/
\.
vue$/
);
export
default
{
name
:
"
MsScheduleMaintain
"
,
components
:
{
CrontabResult
,
Crontab
,
MsScheduleNotification
},
props
:
{
customValidate
:
{
type
:
Function
,
default
:
defaultCustomValidate
},
isReadOnly
:
{
type
:
Boolean
,
default
:
false
},
},
watch
:
{
'
schedule.value
'
()
{
this
.
form
.
cronValue
=
this
.
schedule
.
value
;
}
},
data
()
{
const
validateCron
=
(
rule
,
cronValue
,
callback
)
=>
{
let
customValidate
=
this
.
customValidate
(
this
.
getIntervalTime
());
if
(
!
cronValue
)
{
callback
(
new
Error
(
this
.
$t
(
'
commons.input_content
'
)));
}
else
if
(
!
cronValidate
(
cronValue
))
{
callback
(
new
Error
(
this
.
$t
(
'
schedule.cron_expression_format_error
'
)));
}
else
if
(
!
customValidate
.
pass
)
{
callback
(
new
Error
(
customValidate
.
info
));
}
else
{
callback
();
}
};
return
{
scheduleReceiverOptions
:
[],
operation
:
true
,
dialogVisible
:
false
,
schedule
:
{
value
:
""
,
},
testId
:
String
,
showCron
:
false
,
form
:
{
cronValue
:
""
},
activeName
:
'
first
'
,
rules
:
{
cronValue
:
[{
required
:
true
,
validator
:
validateCron
,
trigger
:
'
blur
'
}],
}
}
},
methods
:
{
currentUser
:
()
=>
{
return
getCurrentUser
();
},
initUserList
()
{
let
param
=
{
name
:
''
,
organizationId
:
this
.
currentUser
().
lastOrganizationId
};
if
(
this
.
isTesterPermission
)
{
this
.
result
=
this
.
$post
(
'
user/org/member/list/all
'
,
param
,
response
=>
{
this
.
scheduleReceiverOptions
=
response
.
data
});
}
},
buildParam
()
{
let
param
=
{};
param
.
notices
=
this
.
tableData
param
.
testId
=
this
.
testId
return
param
;
},
open
(
row
)
{
this
.
testId
=
row
.
id
;
this
.
findSchedule
(
row
.
id
);
this
.
initUserList
();
this
.
dialogVisible
=
true
;
this
.
form
.
cronValue
=
this
.
schedule
.
value
;
listenGoBack
(
this
.
close
);
this
.
activeName
=
'
first
'
},
findSchedule
(){
var
scenarioID
=
this
.
testId
;
this
.
result
=
this
.
$get
(
"
/schedule/findOne/
"
+
scenarioID
+
"
/API_SCENARIO_TEST
"
,
response
=>
{
if
(
response
.
data
!=
null
){
this
.
schedule
=
response
.
data
;
}
else
{
this
.
schedule
=
{};
}
});
},
crontabFill
(
value
,
resultList
)
{
//确定后回传的值
this
.
form
.
cronValue
=
value
;
this
.
$refs
.
crontabResult
.
resultList
=
resultList
;
this
.
$refs
[
'
from
'
].
validate
();
},
showCronDialog
()
{
this
.
showCron
=
true
;
},
saveCron
()
{
this
.
$refs
[
'
from
'
].
validate
((
valid
)
=>
{
if
(
valid
)
{
this
.
intervalShortValidate
();
let
formCronValue
=
this
.
form
.
cronValue
this
.
schedule
.
enable
=
true
;
this
.
schedule
.
value
=
formCronValue
;
this
.
saveSchedule
();
this
.
dialogVisible
=
false
;
}
else
{
return
false
;
}
});
},
saveSchedule
()
{
this
.
checkScheduleEdit
();
let
param
=
{};
param
=
this
.
schedule
;
param
.
resourceId
=
this
.
testId
;
let
url
=
'
/api/automation/schedule/create
'
;
if
(
param
.
id
)
{
url
=
'
/api/automation/schedule/update
'
;
}
this
.
$post
(
url
,
param
,
()
=>
{
this
.
$success
(
this
.
$t
(
'
commons.save_success
'
));
});
},
checkScheduleEdit
()
{
if
(
this
.
create
)
{
this
.
$message
(
this
.
$t
(
'
api_test.environment.please_save_test
'
));
return
false
;
}
return
true
;
},
saveNotice
()
{
let
param
=
this
.
buildParam
();
this
.
result
=
this
.
$post
(
"
notice/save
"
,
param
,
()
=>
{
this
.
$success
(
this
.
$t
(
'
commons.save_success
'
));
})
},
close
()
{
this
.
dialogVisible
=
false
;
this
.
form
.
cronValue
=
''
;
this
.
$refs
[
'
from
'
].
resetFields
();
if
(
!
this
.
schedule
.
value
)
{
this
.
$refs
.
crontabResult
.
resultList
=
[];
}
removeGoBackListener
(
this
.
close
);
},
intervalShortValidate
()
{
if
(
this
.
getIntervalTime
()
<
3
*
60
*
1000
)
{
// return false;
this
.
$info
(
this
.
$t
(
'
schedule.cron_expression_interval_short_error
'
));
}
return
true
;
},
resultListChange
()
{
this
.
$refs
[
'
from
'
].
validate
();
},
getIntervalTime
()
{
let
resultList
=
this
.
$refs
.
crontabResult
.
resultList
;
let
time1
=
new
Date
(
resultList
[
0
]);
let
time2
=
new
Date
(
resultList
[
1
]);
return
time2
-
time1
;
},
},
computed
:
{
isTesterPermission
()
{
return
checkoutTestManagerOrTestUser
();
}
}
}
</
script
>
<
style
scoped
>
.inp
{
width
:
50%
;
margin-right
:
20px
;
}
.el-form-item
{
margin-bottom
:
10px
;
}
</
style
>
frontend/src/business/components/api/automation/schedule/ScheduleNotification.vue
0 → 100644
浏览文件 @
4552b58b
<
template
>
<div>
<el-row>
<el-col
:span=
"10"
>
<el-button
:disabled=
"!isTesterPermission"
icon=
"el-icon-circle-plus-outline"
plain
size=
"mini"
@
click=
"handleAddTaskModel"
>
{{
$t
(
'
organization.message.create_new_notification
'
)
}}
</el-button>
</el-col>
</el-row>
<el-row>
<el-col
:span=
"24"
>
<el-table
:data=
"scheduleTask"
class=
"tb-edit"
border
:cell-style=
"rowClass"
:header-cell-style=
"headClass"
>
<el-table-column
:label=
"$t('schedule.event')"
prop=
"events"
min-width=
"13%"
>
<template
slot-scope=
"scope"
>
<el-select
v-model=
"scope.row.event"
size=
"mini"
:placeholder=
"$t('organization.message.select_events')"
prop=
"events"
:disabled=
"!scope.row.isSet"
>
<el-option
v-for=
"item in scheduleEventOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
>
</el-option>
</el-select>
</
template
>
</el-table-column>
<el-table-column
:label=
"$t('schedule.receiver')"
prop=
"userIds"
min-width=
"18%"
>
<
template
v-slot:default=
"{row}"
>
<el-select
v-model=
"row.userIds"
filterable
multiple
size=
"mini"
:placeholder=
"$t('commons.please_select')"
style=
"width: 100%;"
:disabled=
"!row.isSet"
>
<el-option
v-for=
"item in scheduleReceiverOptions"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
>
</el-option>
</el-select>
</
template
>
</el-table-column>
<el-table-column
:label=
"$t('schedule.receiving_mode')"
prop=
"type"
min-width=
"15%"
>
<
template
slot-scope=
"scope"
>
<el-select
v-model=
"scope.row.type"
:placeholder=
"$t('organization.message.select_receiving_method')"
size=
"mini"
:disabled=
"!scope.row.isSet"
@
change=
"handleEdit(scope.$index, scope.row)"
>
<el-option
v-for=
"item in receiveTypeOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
>
</el-option>
</el-select>
</
template
>
</el-table-column>
<el-table-column
label=
"webhook"
min-width=
"20%"
prop=
"webhook"
>
<
template
v-slot:default=
"scope"
>
<el-input
v-model=
"scope.row.webhook"
placeholder=
"webhook地址"
size=
"mini"
:disabled=
"!scope.row.isSet||!scope.row.isReadOnly"
></el-input>
</
template
>
</el-table-column>
<el-table-column
:label=
"$t('commons.operating')"
prop=
"result"
min-width=
"25%"
>
<
template
v-slot:default=
"scope"
>
<el-button
type=
"success"
size=
"mini"
v-if=
"scope.row.isSet"
v-xpack
@
click=
"handleTemplate(scope.$index,scope.row)"
>
{{
$t
(
'
organization.message.template
'
)
}}
</el-button>
<el-button
type=
"primary"
size=
"mini"
v-show=
"scope.row.isSet"
:disabled=
"!isTesterPermission"
@
click=
"handleAddTask(scope.$index,scope.row)"
>
{{
$t
(
'
commons.add
'
)
}}
</el-button>
<el-button
size=
"mini"
v-show=
"scope.row.isSet"
:disabled=
"!isTesterPermission"
@
click.native.prevent=
"removeRowTask(scope.$index,scheduleTask)"
>
{{
$t
(
'
commons.cancel
'
)
}}
</el-button>
<el-button
type=
"primary"
size=
"mini"
v-show=
"!scope.row.isSet"
:disabled=
"!isTesterPermission"
@
click=
"handleEditTask(scope.$index,scope.row)"
>
{{
$t
(
'
commons.edit
'
)
}}
</el-button>
<el-button
type=
"danger"
icon=
"el-icon-delete"
size=
"mini"
v-show=
"!scope.row.isSet"
:disabled=
"!isTesterPermission"
@
click.native.prevent=
"deleteRowTask(scope.$index,scope.row)"
></el-button>
</
template
>
</el-table-column>
</el-table>
</el-col>
</el-row>
<!-- <notice-template v-xpack ref="noticeTemplate"/>-->
</div>
</template>
<
script
>
import
{
hasLicense
}
from
"
@/common/js/utils
"
;
export
default
{
name
:
"
ScheduleNotification
"
,
components
:
{
},
props
:
{
testId
:
String
,
scheduleReceiverOptions
:
Array
,
isTesterPermission
:
{
type
:
Boolean
,
default
:
true
}
},
data
()
{
return
{
scheduleTask
:
[{
taskType
:
"
scheduleTask
"
,
event
:
""
,
userIds
:
[],
type
:
[],
webhook
:
""
,
isSet
:
true
,
identification
:
""
,
isReadOnly
:
false
,
testId
:
this
.
testId
,
}],
scheduleEventOptions
:
[
{
value
:
'
EXECUTE_SUCCESSFUL
'
,
label
:
this
.
$t
(
'
schedule.event_success
'
)},
{
value
:
'
EXECUTE_FAILED
'
,
label
:
this
.
$t
(
'
schedule.event_failed
'
)}
],
receiveTypeOptions
:
[
{
value
:
'
EMAIL
'
,
label
:
this
.
$t
(
'
organization.message.mail
'
)},
{
value
:
'
NAIL_ROBOT
'
,
label
:
this
.
$t
(
'
organization.message.nail_robot
'
)},
{
value
:
'
WECHAT_ROBOT
'
,
label
:
this
.
$t
(
'
organization.message.enterprise_wechat_robot
'
)}
],
}
},
mounted
()
{
this
.
initForm
()
},
methods
:
{
initForm
()
{
this
.
result
=
this
.
$get
(
'
/notice/search/message/
'
+
this
.
testId
,
response
=>
{
// console.log(response.data);
this
.
scheduleTask
=
response
.
data
;
})
},
handleEdit
(
index
,
data
)
{
data
.
isReadOnly
=
true
;
if
(
data
.
type
===
'
EMAIL
'
)
{
data
.
isReadOnly
=
!
data
.
isReadOnly
;
data
.
webhook
=
''
;
}
},
handleAddTaskModel
()
{
let
Task
=
{};
Task
.
event
=
[];
Task
.
userIds
=
[];
Task
.
type
=
''
;
Task
.
webhook
=
''
;
Task
.
isSet
=
true
;
Task
.
identification
=
''
;
Task
.
taskType
=
'
SCHEDULE_TASK
'
;
Task
.
testId
=
this
.
testId
;
this
.
scheduleTask
.
push
(
Task
);
},
handleEditTask
(
index
,
data
)
{
data
.
isSet
=
true
;
data
.
testId
=
this
.
testId
;
if
(
data
.
type
===
'
EMAIL
'
)
{
data
.
isReadOnly
=
false
;
data
.
webhook
=
''
;
}
else
{
data
.
isReadOnly
=
true
;
}
},
handleAddTask
(
index
,
data
)
{
if
(
data
.
event
&&
data
.
userIds
.
length
>
0
&&
data
.
type
)
{
// console.log(data.type)
if
(
data
.
type
===
'
NAIL_ROBOT
'
||
data
.
type
===
'
WECHAT_ROBOT
'
)
{
if
(
!
data
.
webhook
)
{
this
.
$warning
(
this
.
$t
(
'
organization.message.message_webhook
'
));
}
else
{
this
.
addTask
(
data
)
}
}
else
{
this
.
addTask
(
data
)
}
}
else
{
this
.
$warning
(
this
.
$t
(
'
organization.message.message
'
));
}
},
addTask
(
data
)
{
this
.
result
=
this
.
$post
(
"
/notice/save/message/task
"
,
data
,
()
=>
{
this
.
initForm
()
this
.
$success
(
this
.
$t
(
'
commons.save_success
'
));
})
},
removeRowTask
(
index
,
data
)
{
//移除
if
(
!
data
[
index
].
identification
)
{
data
.
splice
(
index
,
1
)
}
else
{
data
[
index
].
isSet
=
false
;
}
},
deleteRowTask
(
index
,
data
)
{
//删除
this
.
result
=
this
.
$get
(
"
/notice/delete/message/
"
+
data
.
identification
,
response
=>
{
this
.
$success
(
this
.
$t
(
'
commons.delete_success
'
));
this
.
initForm
()
})
},
rowClass
()
{
return
"
text-align:center
"
},
headClass
()
{
return
"
text-align:center;background:'#ededed'
"
},
handleTemplate
(
index
,
row
)
{
if
(
hasLicense
())
{
this
.
$refs
.
noticeTemplate
.
open
(
row
);
}
}
}
}
</
script
>
<
style
scoped
>
.el-row
{
margin-bottom
:
10px
;
}
</
style
>
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录