feat(接口测试): 接口脚本增加站内通知机制
--story=1012023 --user=王孝刚 接口脚本增加预警审核机制 https://www.tapd.cn/55049933/s/1373138
This commit is contained in:
parent
b1025dad23
commit
350816070a
|
@ -43,6 +43,7 @@ import io.metersphere.metadata.service.FileMetadataService;
|
|||
import io.metersphere.plugin.core.MsParameter;
|
||||
import io.metersphere.plugin.core.MsTestElement;
|
||||
import io.metersphere.request.BodyFile;
|
||||
import io.metersphere.service.MsHashTreeService;
|
||||
import io.metersphere.utils.LoggerUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
|
@ -81,6 +82,13 @@ public class ElementUtil {
|
|||
private static final String ASSERTIONS = ElementConstants.ASSERTIONS;
|
||||
private static final String BODY_FILE_DIR = FileUtils.BODY_FILE_DIR;
|
||||
private static final String TEST_BEAN_GUI = "TestBeanGUI";
|
||||
public final static List<String> scriptList = new ArrayList<String>() {{
|
||||
this.add(ElementConstants.JSR223);
|
||||
this.add(ElementConstants.JSR223_PRE);
|
||||
this.add(ElementConstants.JSR223_POST);
|
||||
}};
|
||||
|
||||
|
||||
|
||||
|
||||
public static Map<String, EnvironmentConfig> getEnvironmentConfig(String environmentId, String projectId) {
|
||||
|
@ -1099,4 +1107,49 @@ public class ElementUtil {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Map<String, String> scriptMap(String request) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
if (StringUtils.isBlank(request)) {
|
||||
return map;
|
||||
}
|
||||
JSONObject element = JSONUtil.parseObject(request);
|
||||
toMap(element.getJSONArray(ElementConstants.HASH_TREE), scriptList, map);
|
||||
return map;
|
||||
}
|
||||
|
||||
private static void toMap(JSONArray hashTree, List<String> scriptList, Map<String, String> map) {
|
||||
for (int i = 0; i < hashTree.length(); i++) {
|
||||
JSONObject element = hashTree.optJSONObject(i);
|
||||
if (element == null) {
|
||||
continue;
|
||||
}
|
||||
if (scriptList.contains(element.optString(ElementConstants.TYPE))) {
|
||||
JSONObject elementTarget = JSONUtil.parseObject(element.toString());
|
||||
if (elementTarget.has(ElementConstants.HASH_TREE)) {
|
||||
elementTarget.remove(ElementConstants.HASH_TREE);
|
||||
}
|
||||
map.put(StringUtils.join(element.optString(MsHashTreeService.ID),
|
||||
element.optString(MsHashTreeService.INDEX)),
|
||||
elementTarget.toString());
|
||||
}
|
||||
if (element.has(ElementConstants.HASH_TREE)) {
|
||||
JSONArray elementJSONArray = element.optJSONArray(ElementConstants.HASH_TREE);
|
||||
toMap(elementJSONArray, scriptList, map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isSend(Map<String, String> org, Map<String, String> target) {
|
||||
if (org.size() != target.size() && target.size() > 0) {
|
||||
return true;
|
||||
}
|
||||
for (Map.Entry<String, String> entry : org.entrySet()) {
|
||||
if (target.containsKey(entry.getKey()) && !StringUtils.equals(entry.getValue(), target.get(entry.getKey()))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,9 +28,12 @@ import io.metersphere.log.utils.ReflexObjectUtil;
|
|||
import io.metersphere.log.vo.DetailColumn;
|
||||
import io.metersphere.log.vo.OperatingLogDetails;
|
||||
import io.metersphere.log.vo.api.DefinitionReference;
|
||||
import io.metersphere.notice.service.NotificationService;
|
||||
import io.metersphere.plugin.core.MsTestElement;
|
||||
import io.metersphere.request.OrderRequest;
|
||||
import io.metersphere.request.ResetOrderRequest;
|
||||
import io.metersphere.service.BaseProjectApplicationService;
|
||||
import io.metersphere.service.BaseProjectService;
|
||||
import io.metersphere.service.BaseUserService;
|
||||
import io.metersphere.service.ServiceUtils;
|
||||
import io.metersphere.service.ext.ExtFileAssociationService;
|
||||
|
@ -104,11 +107,18 @@ public class ApiTestCaseService {
|
|||
private ExtTestPlanApiCaseMapper extTestPlanApiCaseMapper;
|
||||
@Resource
|
||||
private ExtApiScenarioReferenceIdMapper extApiScenarioReferenceIdMapper;
|
||||
@Resource
|
||||
private BaseProjectApplicationService baseProjectApplicationService;
|
||||
@Resource
|
||||
private NotificationService notificationService;
|
||||
@Resource
|
||||
private BaseProjectService baseProjectService;
|
||||
|
||||
|
||||
|
||||
private static final String BODY_FILE_DIR = FileUtils.BODY_FILE_DIR;
|
||||
|
||||
private static final String DEFAULT_TIME_DATE = "-3D";
|
||||
|
||||
//查询测试用例详情
|
||||
public ApiTestCaseWithBLOBs getInfoJenkins(String id) {
|
||||
ApiTestCaseWithBLOBs apiTest = apiTestCaseMapper.selectByPrimaryKey(id);
|
||||
|
@ -395,6 +405,7 @@ public class ApiTestCaseService {
|
|||
request.setRequest(tcpApiParamService.parseMsTestElement(request.getRequest()));
|
||||
final ApiTestCaseWithBLOBs test = apiTestCaseMapper.selectByPrimaryKey(request.getId());
|
||||
if (test != null) {
|
||||
String requestOrg = test.getRequest();
|
||||
test.setName(request.getName());
|
||||
test.setCaseStatus(request.getCaseStatus());
|
||||
if (StringUtils.isEmpty(request.getCaseStatus())) {
|
||||
|
@ -420,6 +431,14 @@ public class ApiTestCaseService {
|
|||
}
|
||||
apiTestCaseMapper.updateByPrimaryKeySelective(test);
|
||||
saveFollows(test.getId(), request.getFollows());
|
||||
this.checkAndSendReviewMessage(test.getId(),
|
||||
test.getName(),
|
||||
test.getProjectId(),
|
||||
"接口用例通知",
|
||||
NoticeConstants.TaskType.API_DEFINITION_TASK,
|
||||
requestOrg,
|
||||
test.getRequest()
|
||||
);
|
||||
}
|
||||
// 存储附件关系
|
||||
extFileAssociationService.saveApi(test.getId(), request.getRequest(), FileAssociationTypeEnums.CASE.name());
|
||||
|
@ -486,6 +505,14 @@ public class ApiTestCaseService {
|
|||
apiTestCaseMapper.insert(test);
|
||||
saveFollows(test.getId(), request.getFollows());
|
||||
}
|
||||
this.checkAndSendReviewMessage(test.getId(),
|
||||
test.getName(),
|
||||
test.getProjectId(),
|
||||
"接口用例通知",
|
||||
NoticeConstants.TaskType.API_DEFINITION_TASK,
|
||||
null,
|
||||
test.getRequest()
|
||||
);
|
||||
// 存储附件关系
|
||||
extFileAssociationService.saveApi(test.getId(), request.getRequest(), FileAssociationTypeEnums.CASE.name());
|
||||
return test;
|
||||
|
@ -1306,4 +1333,42 @@ public class ApiTestCaseService {
|
|||
return extApiTestCaseMapper.findPassRateById(id);
|
||||
|
||||
}
|
||||
|
||||
//检查并发送脚本审核的通知
|
||||
@Async
|
||||
public void checkAndSendReviewMessage(String id,
|
||||
String name,
|
||||
String projectId,
|
||||
String title,
|
||||
String resourceType,
|
||||
String requestOrg,
|
||||
String requestTarget) {
|
||||
ProjectApplication reviewLoadTestScript = baseProjectApplicationService.getProjectApplication(
|
||||
projectId, ProjectApplicationType.API_REVIEW_TEST_SCRIPT.name());
|
||||
if (BooleanUtils.toBoolean(reviewLoadTestScript.getTypeValue())) {
|
||||
ProjectApplication reviewerConfig = baseProjectApplicationService.getProjectApplication(
|
||||
projectId, ProjectApplicationType.API_SCRIPT_REVIEWER.name());
|
||||
if (StringUtils.isNotEmpty(reviewerConfig.getTypeValue()) &&
|
||||
baseProjectService.isProjectMember(projectId, reviewerConfig.getTypeValue())) {
|
||||
Map<String, String> org = ElementUtil.scriptMap(requestOrg);
|
||||
Map<String, String> target = ElementUtil.scriptMap(requestTarget);
|
||||
boolean isSend = ElementUtil.isSend(org, target);
|
||||
if (isSend) {
|
||||
Notification notification = new Notification();
|
||||
notification.setTitle(title);
|
||||
notification.setOperator(SessionUtils.getUserId());
|
||||
notification.setOperation(NoticeConstants.Event.REVIEW);
|
||||
notification.setResourceId(id);
|
||||
notification.setResourceName(name);
|
||||
notification.setResourceType(resourceType);
|
||||
notification.setType(NotificationConstants.Type.SYSTEM_NOTICE.name());
|
||||
notification.setStatus(NotificationConstants.Status.UNREAD.name());
|
||||
notification.setCreateTime(System.currentTimeMillis());
|
||||
notification.setReceiver(reviewerConfig.getTypeValue());
|
||||
notificationService.sendAnnouncement(notification);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ import io.metersphere.request.ResetOrderRequest;
|
|||
import io.metersphere.sechedule.ApiScenarioTestJob;
|
||||
import io.metersphere.sechedule.SwaggerUrlImportJob;
|
||||
import io.metersphere.service.*;
|
||||
import io.metersphere.service.definition.ApiTestCaseService;
|
||||
import io.metersphere.service.definition.TcpApiParamService;
|
||||
import io.metersphere.service.ext.ExtApiScheduleService;
|
||||
import io.metersphere.service.ext.ExtFileAssociationService;
|
||||
|
@ -162,6 +163,8 @@ public class ApiScenarioService {
|
|||
private BaseQuotaService baseQuotaService;
|
||||
@Resource
|
||||
private ApiAutomationRelationshipEdgeService apiAutomationRelationshipEdgeService;
|
||||
@Resource
|
||||
private ApiTestCaseService apiTestCaseService;
|
||||
|
||||
private ThreadLocal<Long> currentScenarioOrder = new ThreadLocal<>();
|
||||
|
||||
|
@ -266,7 +269,7 @@ public class ApiScenarioService {
|
|||
extApiScenarioMapper.removeToGcByExample(example);
|
||||
}
|
||||
|
||||
public ApiScenario create(SaveApiScenarioRequest request, List<MultipartFile> bodyFiles, List<MultipartFile> scenarioFiles) {
|
||||
public ApiScenarioWithBLOBs create(SaveApiScenarioRequest request, List<MultipartFile> bodyFiles, List<MultipartFile> scenarioFiles) {
|
||||
checkQuota(request.getProjectId());
|
||||
request.setId(UUID.randomUUID().toString());
|
||||
if (request.getScenarioDefinition() == null) {
|
||||
|
@ -294,6 +297,15 @@ public class ApiScenarioService {
|
|||
apiScenarioReferenceIdService.saveApiAndScenarioRelation(scenario);
|
||||
// 存储依赖关系
|
||||
apiAutomationRelationshipEdgeService.initRelationshipEdge(null, scenario);
|
||||
apiTestCaseService.checkAndSendReviewMessage(
|
||||
scenario.getId(),
|
||||
scenario.getName(),
|
||||
scenario.getProjectId(),
|
||||
"场景用例通知",
|
||||
NoticeConstants.TaskType.API_AUTOMATION_TASK,
|
||||
null,
|
||||
scenario.getScenarioDefinition()
|
||||
);
|
||||
|
||||
uploadFiles(request, bodyFiles, scenarioFiles);
|
||||
return scenario;
|
||||
|
@ -352,7 +364,7 @@ public class ApiScenarioService {
|
|||
}
|
||||
}
|
||||
|
||||
public ApiScenario update(SaveApiScenarioRequest request, List<MultipartFile> bodyFiles, List<MultipartFile> scenarioFiles) {
|
||||
public ApiScenarioWithBLOBs update(SaveApiScenarioRequest request, List<MultipartFile> bodyFiles, List<MultipartFile> scenarioFiles) {
|
||||
checkNameExist(request, false);
|
||||
checkScenarioNum(request);
|
||||
//如果场景有TCP步骤的话,也要做参数计算处理
|
||||
|
@ -399,6 +411,16 @@ public class ApiScenarioService {
|
|||
// 存储依赖关系
|
||||
apiAutomationRelationshipEdgeService.initRelationshipEdge(beforeScenario, scenario);
|
||||
|
||||
apiTestCaseService.checkAndSendReviewMessage(
|
||||
scenario.getId(),
|
||||
scenario.getName(),
|
||||
scenario.getProjectId(),
|
||||
"场景用例通知",
|
||||
NoticeConstants.TaskType.API_AUTOMATION_TASK,
|
||||
beforeScenario.getScenarioDefinition(),
|
||||
scenario.getScenarioDefinition()
|
||||
);
|
||||
|
||||
String defaultVersion = baseProjectVersionMapper.getDefaultVersion(request.getProjectId());
|
||||
if (StringUtils.equalsIgnoreCase(request.getVersionId(), defaultVersion)) {
|
||||
checkAndSetLatestVersion(beforeScenario.getRefId());
|
||||
|
|
|
@ -291,6 +291,7 @@ export default {
|
|||
arr[i].disabled = disabled;
|
||||
arr[i].isCopy = false;
|
||||
arr[i].projectId = this.calcProjectId(arr[i].projectId, id);
|
||||
arr[i].notAddStep = true;
|
||||
// 处理子请求环境
|
||||
let typeArray = ['JDBCPostProcessor', 'JDBCSampler', 'JDBCPreProcessor'];
|
||||
if (typeArray.indexOf(arr[i].type) !== -1) {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
@click="add"
|
||||
type="primary"
|
||||
v-if="tabType !== 'assertionsRule'"
|
||||
:disabled="request.notAddStep"
|
||||
style="background-color: var(--primary_color); border-color: var(--primary_color)">
|
||||
{{ $t('api_test.request.assertions.add') }}
|
||||
</el-button>
|
||||
|
|
|
@ -14,6 +14,16 @@ export function getResource(d) {
|
|||
|
||||
let resourceType = i18n.t('notice.resource.' + d.resourceType);
|
||||
if (!d.operation.startsWith('EXECUTE_')) {
|
||||
if (d.operation.startsWith('REVIEW') && d.resourceType === 'API_DEFINITION_TASK') {
|
||||
resourceType = i18n.t('notice.api_case');
|
||||
}
|
||||
if (d.operation.startsWith('REVIEW') && d.resourceType === 'API_AUTOMATION_TASK') {
|
||||
resourceType = i18n.t('notice.scenario_case');
|
||||
}
|
||||
if (d.operation.startsWith('REVIEW') && d.resourceType === 'ENV_TASK') {
|
||||
resourceType = i18n.t('notice.env_task');
|
||||
}
|
||||
|
||||
return resourceType;
|
||||
}
|
||||
switch (d.resourceType) {
|
||||
|
@ -90,7 +100,9 @@ export function getUrl(d) {
|
|||
url += "/api/definition?caseId=" + d.resourceId;
|
||||
} else if (d.operation.startsWith('MOCK_')) {
|
||||
url += "/api/definition?mockId=" + d.resourceId;
|
||||
} else {
|
||||
}else if (d.operation.startsWith('REVIEW')) {
|
||||
url += "/api/definition?caseId=" + d.resourceId;
|
||||
}else {
|
||||
url += "/api/definition?resourceId=" + d.resourceId;
|
||||
}
|
||||
break;
|
||||
|
@ -115,6 +127,8 @@ export function getUrl(d) {
|
|||
case "TRACK_REPORT_TASK" :
|
||||
url += "/track/testPlan/reportList";
|
||||
break;
|
||||
case"ENV_TASK" :
|
||||
url += "/project/env?resourceId=" + d.resourceId;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -2710,6 +2710,8 @@ const message = {
|
|||
EXECUTE_COMPLETED: " Completed",
|
||||
},
|
||||
api_case: "API Case",
|
||||
scenario_case: "Scenario Case",
|
||||
env_task: "Environment",
|
||||
},
|
||||
permission: {
|
||||
common: {
|
||||
|
|
|
@ -2615,6 +2615,8 @@ const message = {
|
|||
EXECUTE_COMPLETED: "完成",
|
||||
},
|
||||
api_case: "接口用例",
|
||||
scenario_case: "场景用例",
|
||||
env_task: "环境",
|
||||
},
|
||||
permission: {
|
||||
common: {
|
||||
|
|
|
@ -2610,6 +2610,8 @@ const message = {
|
|||
EXECUTE_COMPLETED: "完成",
|
||||
},
|
||||
api_case: "接口用例",
|
||||
scenario_case: "場景用例",
|
||||
env_task: "環境",
|
||||
},
|
||||
permission: {
|
||||
common: {
|
||||
|
|
|
@ -21,6 +21,7 @@ public interface NoticeConstants {
|
|||
String UI_DEFINITION_TASK = "UI_DEFINITION_TASK";
|
||||
String UI_HOME_TASK = "UI_HOME_TASK";
|
||||
String UI_REPORT_TASK = "UI_REPORT_TASK";
|
||||
String ENV_TASK = "ENV_TASK";
|
||||
}
|
||||
|
||||
interface Mode {
|
||||
|
|
|
@ -116,4 +116,12 @@ public enum ProjectApplicationType {
|
|||
* 性能测试脚本评审人
|
||||
*/
|
||||
PERFORMANCE_SCRIPT_REVIEWER,
|
||||
/**
|
||||
* 接口测试是否评审脚本
|
||||
*/
|
||||
API_REVIEW_TEST_SCRIPT,
|
||||
/**
|
||||
* 接口测试脚本评审人
|
||||
*/
|
||||
API_SCRIPT_REVIEWER,
|
||||
}
|
||||
|
|
|
@ -38,4 +38,6 @@ public class ProjectConfig {
|
|||
private Boolean reReview = false;
|
||||
private String performanceScriptReviewer;
|
||||
private Boolean performanceReviewLoadTestScript = false;
|
||||
private String apiScriptReviewer;
|
||||
private Boolean apiReviewTestScript = false;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ import io.metersphere.base.mapper.ext.BaseApiTestEnvironmentMapper;
|
|||
import io.metersphere.base.mapper.ext.BaseEnvironmentGroupMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtApiTestEnvironmentMapper;
|
||||
import io.metersphere.commons.constants.FileAssociationType;
|
||||
import io.metersphere.commons.constants.NoticeConstants;
|
||||
import io.metersphere.commons.constants.NotificationConstants;
|
||||
import io.metersphere.commons.constants.ProjectApplicationType;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.*;
|
||||
|
@ -19,6 +21,7 @@ import io.metersphere.log.vo.DetailColumn;
|
|||
import io.metersphere.log.vo.OperatingLogDetails;
|
||||
import io.metersphere.log.vo.system.SystemReference;
|
||||
import io.metersphere.metadata.service.FileAssociationService;
|
||||
import io.metersphere.notice.service.NotificationService;
|
||||
import io.metersphere.request.BodyFile;
|
||||
import io.metersphere.request.variable.ScenarioVariable;
|
||||
import io.metersphere.service.BaseProjectApplicationService;
|
||||
|
@ -37,6 +40,7 @@ import org.json.JSONArray;
|
|||
import org.json.JSONObject;
|
||||
import org.mybatis.spring.SqlSessionUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
@ -78,8 +82,17 @@ public class BaseEnvironmentService extends NodeTreeService<ApiModuleDTO> {
|
|||
private BaseProjectService baseProjectService;
|
||||
@Resource
|
||||
private BaseProjectApplicationService baseProjectApplicationService;
|
||||
@Resource
|
||||
private NotificationService notificationService;
|
||||
|
||||
public static final String MOCK_EVN_NAME = "Mock环境";
|
||||
|
||||
public static final String POST_STEP = "postStepProcessor";
|
||||
public static final String PRE_STEP = "preStepProcessor";
|
||||
public static final String POST = "postProcessor";
|
||||
public static final String PRE = "preProcessor";
|
||||
public static final String SCRIPT = "script";
|
||||
|
||||
public BaseEnvironmentService() {
|
||||
super(ApiModuleDTO.class);
|
||||
}
|
||||
|
@ -399,6 +412,13 @@ public class BaseEnvironmentService extends NodeTreeService<ApiModuleDTO> {
|
|||
apiTestEnvironmentMapper.insert(request);
|
||||
// 存储附件关系
|
||||
saveEnvironment(request.getId(), request.getConfig(), FileAssociationType.ENVIRONMENT.name());
|
||||
checkAndSendReviewMessage(request.getId(),
|
||||
request.getName(),
|
||||
request.getProjectId(),
|
||||
NoticeConstants.TaskType.ENV_TASK,
|
||||
null,
|
||||
request.getConfig()
|
||||
);
|
||||
return request.getId();
|
||||
}
|
||||
|
||||
|
@ -478,7 +498,17 @@ public class BaseEnvironmentService extends NodeTreeService<ApiModuleDTO> {
|
|||
apiTestEnvironment.setUpdateTime(System.currentTimeMillis());
|
||||
// 存储附件关系
|
||||
saveEnvironment(apiTestEnvironment.getId(), apiTestEnvironment.getConfig(), FileAssociationType.ENVIRONMENT.name());
|
||||
ApiTestEnvironmentWithBLOBs envOrg = apiTestEnvironmentMapper.selectByPrimaryKey(apiTestEnvironment.getId());
|
||||
|
||||
apiTestEnvironmentMapper.updateByPrimaryKeyWithBLOBs(apiTestEnvironment);
|
||||
checkAndSendReviewMessage(apiTestEnvironment.getId(),
|
||||
apiTestEnvironment.getName(),
|
||||
apiTestEnvironment.getProjectId(),
|
||||
NoticeConstants.TaskType.ENV_TASK,
|
||||
envOrg.getConfig(),
|
||||
apiTestEnvironment.getConfig()
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public List<ApiModuleDTO> getNodeTreeByProjectId(String projectId, String protocol) {
|
||||
|
@ -974,4 +1004,72 @@ public class BaseEnvironmentService extends NodeTreeService<ApiModuleDTO> {
|
|||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Async
|
||||
public void checkAndSendReviewMessage(String id,
|
||||
String name,
|
||||
String projectId,
|
||||
String resourceType,
|
||||
String requestOrg,
|
||||
String requestTarget) {
|
||||
ProjectApplication reviewLoadTestScript = baseProjectApplicationService.getProjectApplication(
|
||||
projectId, ProjectApplicationType.API_REVIEW_TEST_SCRIPT.name());
|
||||
if (BooleanUtils.toBoolean(reviewLoadTestScript.getTypeValue())) {
|
||||
ProjectApplication reviewerConfig = baseProjectApplicationService.getProjectApplication(
|
||||
projectId, ProjectApplicationType.API_SCRIPT_REVIEWER.name());
|
||||
if (StringUtils.isNotEmpty(reviewerConfig.getTypeValue()) &&
|
||||
baseProjectService.isProjectMember(projectId, reviewerConfig.getTypeValue())) {
|
||||
Map<String, String> org = scriptMap(requestOrg);
|
||||
Map<String, String> target = scriptMap(requestTarget);
|
||||
boolean isSend = isSend(org, target);
|
||||
if (isSend) {
|
||||
Notification notification = new Notification();
|
||||
notification.setTitle("环境设置");
|
||||
notification.setOperator(SessionUtils.getUserId());
|
||||
notification.setOperation(NoticeConstants.Event.REVIEW);
|
||||
notification.setResourceId(id);
|
||||
notification.setResourceName(name);
|
||||
notification.setResourceType(resourceType);
|
||||
notification.setType(NotificationConstants.Type.SYSTEM_NOTICE.name());
|
||||
notification.setStatus(NotificationConstants.Status.UNREAD.name());
|
||||
notification.setCreateTime(System.currentTimeMillis());
|
||||
notification.setReceiver(reviewerConfig.getTypeValue());
|
||||
notificationService.sendAnnouncement(notification);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, String> scriptMap(String request) {
|
||||
Map<Object, Object> configMap = JSON.parseObject(request, Map.class);
|
||||
Map<String, String> map = new HashMap<>();
|
||||
JSONObject configObj = new JSONObject(configMap);
|
||||
toMap(map, configObj, POST_STEP, PRE_STEP);
|
||||
toMap(map, configObj, PRE, POST);
|
||||
return map;
|
||||
}
|
||||
|
||||
private static void toMap(Map<String, String> map, JSONObject configObj, String pre, String post) {
|
||||
JSONObject preProcessor = configObj.optJSONObject(pre);
|
||||
if (StringUtils.isNotBlank(preProcessor.optString(SCRIPT))) {
|
||||
map.put(pre, preProcessor.optString(SCRIPT));
|
||||
}
|
||||
JSONObject postProcessor = configObj.optJSONObject(post);
|
||||
if (StringUtils.isNotBlank(postProcessor.optString(SCRIPT))) {
|
||||
map.put(post, postProcessor.optString(SCRIPT));
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isSend(Map<String, String> orgMap, Map<String, String> targetMap) {
|
||||
if (orgMap.size() != targetMap.size() &&
|
||||
targetMap.size() > 0) {
|
||||
return true;
|
||||
}
|
||||
for (Map.Entry<String, String> entry : orgMap.entrySet()) {
|
||||
if (targetMap.containsKey(entry.getKey()) && !StringUtils.equals(entry.getValue(), targetMap.get(entry.getKey()))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,3 +7,8 @@ export function batchModifyAppSetting(params) {
|
|||
export function getProjectAppSetting(projectId) {
|
||||
return get(`/project_application/get/config/${projectId}`);
|
||||
}
|
||||
|
||||
export function getProjectApplicationConfig(projectId, type) {
|
||||
let url = '/project_application/get/' + projectId + type;
|
||||
return get(url);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,10 @@ export function getEnvironmentPages(goPage, pageSize, param) {
|
|||
return post(`/environment/list/${goPage}/${pageSize}`, param);
|
||||
}
|
||||
|
||||
export function getEnvironment(id) {
|
||||
return get(`/environment/get/${id}`);
|
||||
}
|
||||
|
||||
export function getEnvironments(projectId) {
|
||||
return get(`/environment/list/${projectId}`);
|
||||
}
|
||||
|
|
|
@ -232,6 +232,26 @@
|
|||
></el-switch>
|
||||
</template>
|
||||
</app-manage-item>
|
||||
<!-- 接口审核 -->
|
||||
<reviewer-config
|
||||
:name="$t('pj.api_script_review')"
|
||||
:popTitle="$t('pj.api_script_review_tips')"
|
||||
:reviewers="userInProject"
|
||||
:reviewer.sync="config.apiScriptReviewer"
|
||||
:reviewerSwitch.sync="config.apiReviewTestScript"
|
||||
@reviewerChange="
|
||||
switchChange(
|
||||
'API_SCRIPT_REVIEWER',
|
||||
config.apiScriptReviewer
|
||||
)
|
||||
"
|
||||
@chooseChange="
|
||||
switchChange(
|
||||
'API_REVIEW_TEST_SCRIPT',
|
||||
config.apiReviewTestScript
|
||||
)
|
||||
"
|
||||
/>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :span="8" class="commons-view-setting">
|
||||
|
@ -384,7 +404,8 @@
|
|||
:name="$t('pj.load_test_script_review')"
|
||||
:popTitle="$t('pj.load_test_script_review_detail')"
|
||||
:reviewers="userInProject"
|
||||
:config.sync="config"
|
||||
:reviewer.sync="config.performanceScriptReviewer"
|
||||
:reviewerSwitch.sync="config.performanceReviewLoadTestScript"
|
||||
@reviewerChange="
|
||||
switchChange(
|
||||
'PERFORMANCE_SCRIPT_REVIEWER',
|
||||
|
@ -676,6 +697,8 @@ export default {
|
|||
reReview: false,
|
||||
performanceScriptReviewer: "",
|
||||
performanceReviewLoadTestScript: false,
|
||||
apiScriptReviewer: "",
|
||||
apiReviewTestScript: false,
|
||||
},
|
||||
showRuleSetting: false,
|
||||
showSyncTimeSetting: true,
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<template #middle>
|
||||
<span>{{ $t("pj.reviewers") }}</span>
|
||||
<el-select
|
||||
v-model="config.performanceScriptReviewer"
|
||||
v-model="reviewerSelect"
|
||||
@change="reviewerChange"
|
||||
size="mini"
|
||||
style="margin-left: 5px"
|
||||
|
@ -39,7 +39,7 @@
|
|||
</template>
|
||||
<template #append>
|
||||
<el-switch
|
||||
v-model="config.performanceReviewLoadTestScript"
|
||||
v-model="reviewerSwitchSelect"
|
||||
@change="switchChange"
|
||||
></el-switch>
|
||||
</template>
|
||||
|
@ -56,23 +56,36 @@ export default {
|
|||
name: String,
|
||||
popTitle: String,
|
||||
reviewers: Array,
|
||||
config: Object,
|
||||
reviewer: String,
|
||||
reviewerSwitch: Boolean,
|
||||
},
|
||||
setup() {
|
||||
return {};
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
return {
|
||||
reviewerSelect: this.reviewer,
|
||||
reviewerSwitchSelect: this.reviewerSwitch,
|
||||
};
|
||||
},
|
||||
computed: {},
|
||||
watch: {},
|
||||
watch: {
|
||||
reviewer(val) {
|
||||
this.reviewerSelect = val;
|
||||
},
|
||||
reviewerSwitch(val) {
|
||||
this.reviewerSwitchSelect = val;
|
||||
},
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
methods: {
|
||||
switchChange() {
|
||||
switchChange(val) {
|
||||
this.$emit("update:reviewerSwitch", val);
|
||||
this.$emit("chooseChange");
|
||||
},
|
||||
reviewerChange() {
|
||||
reviewerChange(val) {
|
||||
this.$emit("update:reviewer", val);
|
||||
this.$emit("reviewerChange");
|
||||
},
|
||||
},
|
||||
|
|
|
@ -148,7 +148,7 @@ import MsMainContainer from "metersphere-frontend/src/components/MsMainContainer
|
|||
import MsContainer from "metersphere-frontend/src/components/MsContainer";
|
||||
import MsDialogHeader from "metersphere-frontend/src/components/MsDialogHeader";
|
||||
import {listAllProject} from "../../../api/project";
|
||||
import {delEnvironmentById, getEnvironmentPages} from "../../../api/environment";
|
||||
import {delEnvironmentById, getEnvironmentPages, getEnvironment} from "../../../api/environment";
|
||||
import i18n from "@/i18n";
|
||||
|
||||
export default {
|
||||
|
@ -196,7 +196,18 @@ export default {
|
|||
isFullScreen: false //是否全屏
|
||||
}
|
||||
},
|
||||
created() {
|
||||
mounted() {
|
||||
//跳转环境编辑页面
|
||||
if (this.$route && this.$route.query && this.$route.query.resourceId) {
|
||||
let id = this.$route.query.resourceId;
|
||||
getEnvironment(id).then(response => {
|
||||
if (response.data) {
|
||||
this.editEnv(response.data);
|
||||
} else {
|
||||
this.$error(this.$t('environment.get_env_failed'));
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
activated() {
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
<el-col :span="codeSpan">
|
||||
<el-form-item>
|
||||
<template v-slot>
|
||||
<div style="position: relative;">
|
||||
<el-tabs v-model="activeName">
|
||||
<div style="position: relative;" :class="{'button-color': apiReviewTestScript}">
|
||||
<el-tabs v-model="activeName" >
|
||||
<el-tab-pane :label="$t('project.code_segment.segment')" name="code">
|
||||
<ms-code-edit
|
||||
v-if="isCodeEditAlive"
|
||||
|
@ -104,6 +104,7 @@ import ScriptNavMenu from "metersphere-frontend/src/components/environment/snipp
|
|||
import {getCodeSnippetById, modifyCodeSnippet, saveCodeSnippet} from "../../../api/custom-func";
|
||||
import FunctionRun from "./FunctionRun";
|
||||
import {TYPE_TO_C} from "metersphere-frontend/src/model/Setting";
|
||||
import {getProjectApplicationConfig} from "../../../api/app-setting";
|
||||
|
||||
export default {
|
||||
name: "EditFunction",
|
||||
|
@ -167,9 +168,17 @@ export default {
|
|||
response: {},
|
||||
request: {},
|
||||
debug: true,
|
||||
console: this.$t('project.code_segment.no_result')
|
||||
console: this.$t('project.code_segment.no_result'),
|
||||
apiReviewTestScript: false
|
||||
}
|
||||
},
|
||||
activated() {
|
||||
getProjectApplicationConfig(getCurrentProjectID(), '/API_REVIEW_TEST_SCRIPT').then((res) => {
|
||||
if (res.data && res.data.typeValue) {
|
||||
this.apiReviewTestScript = res.data.typeValue === 'true';
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
open(data) {
|
||||
this.activeName = "code";
|
||||
|
@ -263,6 +272,10 @@ export default {
|
|||
});
|
||||
},
|
||||
handleTest() {
|
||||
if (this.apiReviewTestScript) {
|
||||
this.$warning(this.$t('pj.script_warning'));
|
||||
return;
|
||||
}
|
||||
this.activeName = "result";
|
||||
this.console = this.$t('project.code_segment.no_result');
|
||||
this.reloadResult();
|
||||
|
@ -300,7 +313,7 @@ export default {
|
|||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style lang="scss" scoped>
|
||||
.template-title {
|
||||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
|
@ -344,4 +357,12 @@ export default {
|
|||
color: #935aa1;
|
||||
}
|
||||
|
||||
.button-color{
|
||||
.el-button--primary{
|
||||
color: #FFF !important;
|
||||
background-color: rgb(188, 156, 195) !important;
|
||||
border-color: rgb(188, 156, 195) !important;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -8,10 +8,13 @@ const message = {
|
|||
"(Environment configuration with the same name filtered {0})",
|
||||
check_third_project_success: "inspection passed",
|
||||
api_run_pool_title: "Interface execution resource pool",
|
||||
api_script_review: "Interface script review",
|
||||
api_script_review_tips: "User review must be specified when interface use cases include script steps",
|
||||
reviewers: "Reviewers",
|
||||
load_test_script_review: "Performance test script review",
|
||||
load_test_script_review_detail:
|
||||
"Performance test script file upload must specify user review",
|
||||
script_warning:"The script has enabled the review mechanism and cannot test the script on the current page"
|
||||
},
|
||||
file_manage: {
|
||||
my_file: "My File",
|
||||
|
@ -59,6 +62,7 @@ const message = {
|
|||
cancel_ui_relevane: "Relevant",
|
||||
re_ui_relevane: "Relevane",
|
||||
relevance_ui: "Relevance login scene/command",
|
||||
get_env_failed: "Jump environment deleted!",
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@ const message = {
|
|||
reviewers: "审核人",
|
||||
load_test_script_review: "性能脚本审核",
|
||||
load_test_script_review_detail: "上传性能测试脚本文件须指定用户审核",
|
||||
api_script_review: "接口脚本审核",
|
||||
api_script_review_tips: "接口用例包含脚本步骤时须指定用户审核",
|
||||
script_warning:"脚本已启用审核机制,无法在当前页面测试脚本"
|
||||
},
|
||||
file_manage: {
|
||||
my_file: "我的文件",
|
||||
|
@ -57,6 +60,7 @@ const message = {
|
|||
cancel_ui_relevane: "取消关联",
|
||||
re_ui_relevane: "重新关联",
|
||||
relevance_ui: "关联登录场景/指令",
|
||||
get_env_failed: "跳转环境被删除!",
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -7,9 +7,12 @@ const message = {
|
|||
environment_import_repeat_tip: "(已過濾同名稱的環境配置 {0})",
|
||||
check_third_project_success: "檢查通過",
|
||||
api_run_pool_title: "接口執行資源池",
|
||||
api_script_review: "接口腳本審核",
|
||||
api_script_review_tips: "接口用例包含腳本步驟時須指定用戶審核",
|
||||
reviewers: "審核人",
|
||||
load_test_script_review: "性能腳本審核",
|
||||
load_test_script_review_detail: "上傳性能測試腳本文件須指定用戶審核",
|
||||
script_warning:"腳本已啟用審核機制,無法在當前頁面測試腳本"
|
||||
},
|
||||
file_manage: {
|
||||
my_file: "我的文件",
|
||||
|
@ -57,6 +60,7 @@ const message = {
|
|||
cancel_ui_relevane: "取消關聯",
|
||||
re_ui_relevane: "重新關聯",
|
||||
relevance_ui: "關聯登錄場景/指令",
|
||||
get_env_failed: "跳轉環境被删除!",
|
||||
},
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue