Merge branch 'master' of https://github.com/metersphere/metersphere
This commit is contained in:
commit
41cfc77a3e
|
@ -20,6 +20,7 @@ import io.metersphere.commons.utils.PageUtils;
|
|||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.controller.request.QueryScheduleRequest;
|
||||
import io.metersphere.controller.request.ScheduleRequest;
|
||||
import io.metersphere.dto.ScheduleDao;
|
||||
import io.metersphere.performance.service.PerformanceTestService;
|
||||
import io.metersphere.service.CheckPermissionService;
|
||||
|
@ -104,7 +105,7 @@ public class APITestController {
|
|||
}
|
||||
|
||||
@PostMapping(value = "/schedule/create")
|
||||
public void createSchedule(@RequestBody Schedule request) {
|
||||
public void createSchedule(@RequestBody ScheduleRequest request) {
|
||||
apiTestService.createSchedule(request);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import io.metersphere.commons.constants.RoleConstants;
|
|||
import io.metersphere.commons.utils.PageUtils;
|
||||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.controller.request.ScheduleRequest;
|
||||
import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest;
|
||||
import io.metersphere.track.request.testplan.FileOperationRequest;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
|
@ -149,7 +150,7 @@ public class ApiAutomationController {
|
|||
}
|
||||
|
||||
@PostMapping(value = "/schedule/create")
|
||||
public void createSchedule(@RequestBody Schedule request) {
|
||||
public void createSchedule(@RequestBody ScheduleRequest request) {
|
||||
apiAutomationService.createSchedule(request);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import io.metersphere.commons.utils.CronUtils;
|
|||
import io.metersphere.commons.utils.PageUtils;
|
||||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.controller.request.ScheduleRequest;
|
||||
import io.metersphere.service.CheckPermissionService;
|
||||
import io.metersphere.service.ScheduleService;
|
||||
import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest;
|
||||
|
@ -156,7 +157,7 @@ public class ApiDefinitionController {
|
|||
|
||||
//定时任务创建
|
||||
@PostMapping(value = "/schedule/create")
|
||||
public void createSchedule(@RequestBody Schedule request) {
|
||||
public void createSchedule(@RequestBody ScheduleRequest request) {
|
||||
apiDefinitionService.createSchedule(request);
|
||||
}
|
||||
@PostMapping(value = "/schedule/update")
|
||||
|
|
|
@ -63,7 +63,7 @@ public class MsAssertions extends MsTestElement {
|
|||
private ResponseAssertion responseAssertion(MsAssertionRegex assertionRegex) {
|
||||
ResponseAssertion assertion = new ResponseAssertion();
|
||||
assertion.setEnabled(this.isEnable());
|
||||
assertion.setName(assertionRegex.getDescription());
|
||||
assertion.setName(StringUtils.isNotEmpty(this.getName()) ? this.getName() : assertionRegex.getDescription());
|
||||
assertion.setProperty(TestElement.TEST_CLASS, ResponseAssertion.class.getName());
|
||||
assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("AssertionGui"));
|
||||
assertion.setAssumeSuccess(assertionRegex.isAssumeSuccess());
|
||||
|
@ -88,7 +88,7 @@ public class MsAssertions extends MsTestElement {
|
|||
private JSONPathAssertion jsonPathAssertion(MsAssertionJsonPath assertionJsonPath) {
|
||||
JSONPathAssertion assertion = new JSONPathAssertion();
|
||||
assertion.setEnabled(this.isEnable());
|
||||
assertion.setName(StringUtils.isEmpty(assertionJsonPath.getDescription()) ? "JSONPathAssertion" : assertionJsonPath.getDescription());
|
||||
assertion.setName(StringUtils.isNotEmpty(this.getName()) ? this.getName() : "JSONPathAssertion");
|
||||
assertion.setProperty(TestElement.TEST_CLASS, JSONPathAssertion.class.getName());
|
||||
assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("JSONPathAssertionGui"));
|
||||
assertion.setJsonPath(assertionJsonPath.getExpression());
|
||||
|
@ -96,7 +96,7 @@ public class MsAssertions extends MsTestElement {
|
|||
assertion.setJsonValidationBool(true);
|
||||
assertion.setExpectNull(false);
|
||||
assertion.setInvert(false);
|
||||
assertion.setProperty("ASS_OPTION",assertionJsonPath.getOption());
|
||||
assertion.setProperty("ASS_OPTION", assertionJsonPath.getOption());
|
||||
if (StringUtils.isEmpty(assertionJsonPath.getOption()) || "REGEX".equals(assertionJsonPath.getOption())) {
|
||||
assertion.setIsRegex(true);
|
||||
} else {
|
||||
|
@ -108,7 +108,7 @@ public class MsAssertions extends MsTestElement {
|
|||
private XPath2Assertion xPath2Assertion(MsAssertionXPath2 assertionXPath2) {
|
||||
XPath2Assertion assertion = new XPath2Assertion();
|
||||
assertion.setEnabled(this.isEnable());
|
||||
assertion.setName(StringUtils.isEmpty(assertionXPath2.getExpression()) ? "XPath2Assertion" : assertionXPath2.getExpression());
|
||||
assertion.setName(StringUtils.isNotEmpty(this.getName()) ? this.getName() : "XPath2Assertion");
|
||||
assertion.setProperty(TestElement.TEST_CLASS, XPath2Assertion.class.getName());
|
||||
assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("XPath2AssertionGui"));
|
||||
assertion.setXPathString(assertionXPath2.getExpression());
|
||||
|
@ -119,7 +119,7 @@ public class MsAssertions extends MsTestElement {
|
|||
private DurationAssertion durationAssertion(MsAssertionDuration assertionDuration) {
|
||||
DurationAssertion assertion = new DurationAssertion();
|
||||
assertion.setEnabled(this.isEnable());
|
||||
assertion.setName("Response In Time: " + assertionDuration.getValue());
|
||||
assertion.setName(StringUtils.isNotEmpty(this.getName()) ? this.getName() : "Response In Time: " + assertionDuration.getValue());
|
||||
assertion.setProperty(TestElement.TEST_CLASS, DurationAssertion.class.getName());
|
||||
assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("DurationAssertionGui"));
|
||||
assertion.setAllowedDuration(assertionDuration.getValue());
|
||||
|
@ -129,7 +129,7 @@ public class MsAssertions extends MsTestElement {
|
|||
private JSR223Assertion jsr223Assertion(MsAssertionJSR223 assertionJSR223) {
|
||||
JSR223Assertion assertion = new JSR223Assertion();
|
||||
assertion.setEnabled(this.isEnable());
|
||||
assertion.setName(StringUtils.isEmpty(assertionJSR223.getDesc()) ? "JSR223Assertion" : assertionJSR223.getDesc());
|
||||
assertion.setName(StringUtils.isNotEmpty(this.getName()) ? this.getName() : "JSR223Assertion");
|
||||
assertion.setProperty(TestElement.TEST_CLASS, JSR223Assertion.class.getName());
|
||||
assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI"));
|
||||
assertion.setProperty("cacheKey", "true");
|
||||
|
|
|
@ -66,7 +66,7 @@ public class MsExtract extends MsTestElement {
|
|||
|
||||
RegexExtractor extractor = new RegexExtractor();
|
||||
extractor.setEnabled(this.isEnable());
|
||||
extractor.setName(extractRegex.getVariable() + " RegexExtractor");
|
||||
extractor.setName(StringUtils.isNotEmpty(this.getName()) ? this.getName() : " RegexExtractor");
|
||||
extractor.setProperty(TestElement.TEST_CLASS, RegexExtractor.class.getName());
|
||||
extractor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("RegexExtractorGui"));
|
||||
extractor.setRefName(extractRegex.getVariable());
|
||||
|
@ -84,7 +84,7 @@ public class MsExtract extends MsTestElement {
|
|||
private XPath2Extractor xPath2Extractor(MsExtractXPath extractXPath, StringJoiner extract) {
|
||||
XPath2Extractor extractor = new XPath2Extractor();
|
||||
extractor.setEnabled(this.isEnable());
|
||||
extractor.setName(extractXPath.getVariable() + " XPath2Extractor");
|
||||
extractor.setName(StringUtils.isNotEmpty(this.getName()) ? this.getName() : " XPath2Extractor");
|
||||
extractor.setProperty(TestElement.TEST_CLASS, XPath2Extractor.class.getName());
|
||||
extractor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("XPath2ExtractorGui"));
|
||||
extractor.setRefName(extractXPath.getVariable());
|
||||
|
@ -99,7 +99,7 @@ public class MsExtract extends MsTestElement {
|
|||
private JSONPostProcessor jsonPostProcessor(MsExtractJSONPath extractJSONPath, StringJoiner extract) {
|
||||
JSONPostProcessor extractor = new JSONPostProcessor();
|
||||
extractor.setEnabled(this.isEnable());
|
||||
extractor.setName(extractJSONPath.getVariable() + " JSONExtractor");
|
||||
extractor.setName(StringUtils.isNotEmpty(this.getName()) ? this.getName() : " JSONExtractor");
|
||||
extractor.setProperty(TestElement.TEST_CLASS, JSONPostProcessor.class.getName());
|
||||
extractor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("JSONPostProcessorGui"));
|
||||
extractor.setRefNames(extractJSONPath.getVariable());
|
||||
|
|
|
@ -253,7 +253,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
|
|||
String url2 = reportUrl;
|
||||
if (StringUtils.isEmpty(url)) {
|
||||
url = baseSystemConfigDTO.getUrl() + "/#/api/report/view/" + report.getId();
|
||||
url2 = baseSystemConfigDTO.getUrl() + "/#/api/automation/report";
|
||||
url2 = baseSystemConfigDTO.getUrl() + "/#/api/automation/report/view/" + report.getId();
|
||||
}
|
||||
String successContext = "";
|
||||
String failedContext = "";
|
||||
|
|
|
@ -21,6 +21,7 @@ import io.metersphere.commons.constants.ScheduleType;
|
|||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.controller.request.QueryScheduleRequest;
|
||||
import io.metersphere.controller.request.ScheduleRequest;
|
||||
import io.metersphere.dto.ScheduleDao;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.job.sechedule.ApiTestJob;
|
||||
|
@ -328,12 +329,12 @@ public class APITestService {
|
|||
addOrUpdateApiTestCronJob(request);
|
||||
}
|
||||
|
||||
public void createSchedule(Schedule request) {
|
||||
public void createSchedule(ScheduleRequest request) {
|
||||
scheduleService.addSchedule(buildApiTestSchedule(request));
|
||||
addOrUpdateApiTestCronJob(request);
|
||||
}
|
||||
|
||||
private Schedule buildApiTestSchedule(Schedule request) {
|
||||
private Schedule buildApiTestSchedule(ScheduleRequest request) {
|
||||
Schedule schedule = scheduleService.buildApiTestSchedule(request);
|
||||
schedule.setJob(ApiTestJob.class.getName());
|
||||
schedule.setGroup(ScheduleGroup.API_TEST.name());
|
||||
|
|
|
@ -31,6 +31,7 @@ import io.metersphere.base.mapper.ext.ExtTestPlanScenarioCaseMapper;
|
|||
import io.metersphere.commons.constants.*;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.controller.request.ScheduleRequest;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.job.sechedule.ApiScenarioTestJob;
|
||||
import io.metersphere.job.sechedule.TestPlanTestJob;
|
||||
|
@ -717,7 +718,7 @@ public class ApiAutomationService {
|
|||
return apiScenarioMapper.selectByExampleWithBLOBs(example);
|
||||
}
|
||||
|
||||
public void createSchedule(Schedule request) {
|
||||
public void createSchedule(ScheduleRequest request) {
|
||||
Schedule schedule = scheduleService.buildApiTestSchedule(request);
|
||||
schedule.setJob(ApiScenarioTestJob.class.getName());
|
||||
schedule.setGroup(ScheduleGroup.API_SCENARIO_TEST.name());
|
||||
|
|
|
@ -28,6 +28,7 @@ import io.metersphere.base.mapper.ext.*;
|
|||
import io.metersphere.commons.constants.*;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.controller.request.ScheduleRequest;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.job.sechedule.SwaggerUrlImportJob;
|
||||
import io.metersphere.service.FileService;
|
||||
|
@ -197,7 +198,7 @@ public class ApiDefinitionService {
|
|||
.andProtocolEqualTo(request.getProtocol()).andPathEqualTo(request.getPath())
|
||||
.andProjectIdEqualTo(request.getProjectId()).andIdNotEqualTo(request.getId());
|
||||
Project project = projectMapper.selectByPrimaryKey(request.getProjectId());
|
||||
if (apiDefinitionMapper.countByExample(example) > 0 && (project.getRepeatable() == null || !project.getRepeatable())) {
|
||||
if (apiDefinitionMapper.countByExample(example) > 0 && (project == null || project.getRepeatable() == null || !project.getRepeatable())) {
|
||||
MSException.throwException(Translator.get("api_definition_url_not_repeating"));
|
||||
}
|
||||
} else {
|
||||
|
@ -702,7 +703,7 @@ public class ApiDefinitionService {
|
|||
}
|
||||
|
||||
/*swagger定时导入*/
|
||||
public void createSchedule(Schedule request) {
|
||||
public void createSchedule(ScheduleRequest request) {
|
||||
/*保存swaggerUrl*/
|
||||
SwaggerUrlProject swaggerUrlProject = new SwaggerUrlProject();
|
||||
swaggerUrlProject.setId(UUID.randomUUID().toString());
|
||||
|
|
|
@ -126,8 +126,14 @@ public class ApiTestCaseService {
|
|||
if (!CollectionUtils.isEmpty(userIds)) {
|
||||
Map<String, User> userMap = userService.queryNameByIds(userIds);
|
||||
apiTestCases.forEach(caseResult -> {
|
||||
caseResult.setCreateUser(userMap.get(caseResult.getCreateUserId()).getName());
|
||||
caseResult.setUpdateUser(userMap.get(caseResult.getUpdateUserId()).getName());
|
||||
User createUser = userMap.get(caseResult.getCreateUserId());
|
||||
if (createUser != null) {
|
||||
caseResult.setCreateUser(createUser.getName());
|
||||
}
|
||||
User updateUser = userMap.get(caseResult.getUpdateUserId());
|
||||
if (updateUser != null) {
|
||||
caseResult.setUpdateUser(updateUser.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,15 +33,4 @@ public class Schedule implements Serializable {
|
|||
private String customData;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
//定时任务来源: 测试计划/测试场景
|
||||
private String scheduleFrom;
|
||||
|
||||
private String projectId;
|
||||
|
||||
private String moduleId;
|
||||
|
||||
private String modulePath;
|
||||
|
||||
private String modeId;
|
||||
}
|
|
@ -46,5 +46,9 @@ public class TestCase implements Serializable {
|
|||
|
||||
private String demandName;
|
||||
|
||||
private String followPeople;
|
||||
|
||||
private String status;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
|
@ -1463,6 +1463,146 @@ public class TestCaseExample {
|
|||
addCriterion("demand_name not between", value1, value2, "demandName");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFollowPeopleIsNull() {
|
||||
addCriterion("follow_people is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFollowPeopleIsNotNull() {
|
||||
addCriterion("follow_people is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFollowPeopleEqualTo(String value) {
|
||||
addCriterion("follow_people =", value, "followPeople");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFollowPeopleNotEqualTo(String value) {
|
||||
addCriterion("follow_people <>", value, "followPeople");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFollowPeopleGreaterThan(String value) {
|
||||
addCriterion("follow_people >", value, "followPeople");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFollowPeopleGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("follow_people >=", value, "followPeople");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFollowPeopleLessThan(String value) {
|
||||
addCriterion("follow_people <", value, "followPeople");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFollowPeopleLessThanOrEqualTo(String value) {
|
||||
addCriterion("follow_people <=", value, "followPeople");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFollowPeopleLike(String value) {
|
||||
addCriterion("follow_people like", value, "followPeople");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFollowPeopleNotLike(String value) {
|
||||
addCriterion("follow_people not like", value, "followPeople");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFollowPeopleIn(List<String> values) {
|
||||
addCriterion("follow_people in", values, "followPeople");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFollowPeopleNotIn(List<String> values) {
|
||||
addCriterion("follow_people not in", values, "followPeople");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFollowPeopleBetween(String value1, String value2) {
|
||||
addCriterion("follow_people between", value1, value2, "followPeople");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andFollowPeopleNotBetween(String value1, String value2) {
|
||||
addCriterion("follow_people not between", value1, value2, "followPeople");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andStatusIsNull() {
|
||||
addCriterion("`status` is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andStatusIsNotNull() {
|
||||
addCriterion("`status` is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andStatusEqualTo(String value) {
|
||||
addCriterion("`status` =", value, "status");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andStatusNotEqualTo(String value) {
|
||||
addCriterion("`status` <>", value, "status");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andStatusGreaterThan(String value) {
|
||||
addCriterion("`status` >", value, "status");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andStatusGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("`status` >=", value, "status");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andStatusLessThan(String value) {
|
||||
addCriterion("`status` <", value, "status");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andStatusLessThanOrEqualTo(String value) {
|
||||
addCriterion("`status` <=", value, "status");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andStatusLike(String value) {
|
||||
addCriterion("`status` like", value, "status");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andStatusNotLike(String value) {
|
||||
addCriterion("`status` not like", value, "status");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andStatusIn(List<String> values) {
|
||||
addCriterion("`status` in", values, "status");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andStatusNotIn(List<String> values) {
|
||||
addCriterion("`status` not in", values, "status");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andStatusBetween(String value1, String value2) {
|
||||
addCriterion("`status` between", value1, value2, "status");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andStatusNotBetween(String value1, String value2) {
|
||||
addCriterion("`status` not between", value1, value2, "status");
|
||||
return (Criteria) this;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Criteria extends GeneratedCriteria {
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="io.metersphere.base.mapper.TestCaseMapper">
|
||||
<resultMap id="BaseResultMap" type="io.metersphere.base.domain.TestCase">
|
||||
<id column="id" jdbcType="VARCHAR" property="id" />
|
||||
<result column="node_id" jdbcType="VARCHAR" property="nodeId" />
|
||||
<result column="node_path" jdbcType="VARCHAR" property="nodePath" />
|
||||
<result column="project_id" jdbcType="VARCHAR" property="projectId" />
|
||||
<result column="name" jdbcType="VARCHAR" property="name" />
|
||||
<result column="type" jdbcType="VARCHAR" property="type" />
|
||||
<result column="maintainer" jdbcType="VARCHAR" property="maintainer" />
|
||||
<result column="priority" jdbcType="VARCHAR" property="priority" />
|
||||
<id column="id" jdbcType="VARCHAR" property="id"/>
|
||||
<result column="node_id" jdbcType="VARCHAR" property="nodeId"/>
|
||||
<result column="node_path" jdbcType="VARCHAR" property="nodePath"/>
|
||||
<result column="project_id" jdbcType="VARCHAR" property="projectId"/>
|
||||
<result column="name" jdbcType="VARCHAR" property="name"/>
|
||||
<result column="type" jdbcType="VARCHAR" property="type"/>
|
||||
<result column="maintainer" jdbcType="VARCHAR" property="maintainer"/>
|
||||
<result column="priority" jdbcType="VARCHAR" property="priority"/>
|
||||
<result column="method" jdbcType="VARCHAR" property="method"/>
|
||||
<result column="prerequisite" jdbcType="VARCHAR" property="prerequisite"/>
|
||||
<result column="create_time" jdbcType="BIGINT" property="createTime"/>
|
||||
|
@ -22,6 +22,8 @@
|
|||
<result column="tags" jdbcType="VARCHAR" property="tags"/>
|
||||
<result column="demand_id" jdbcType="VARCHAR" property="demandId"/>
|
||||
<result column="demand_name" jdbcType="VARCHAR" property="demandName"/>
|
||||
<result column="follow_people" jdbcType="VARCHAR" property="followPeople"/>
|
||||
<result column="status" jdbcType="VARCHAR" property="status"/>
|
||||
</resultMap>
|
||||
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.TestCaseWithBLOBs">
|
||||
<result column="remark" jdbcType="LONGVARCHAR" property="remark" />
|
||||
|
@ -88,7 +90,7 @@
|
|||
<sql id="Base_Column_List">
|
||||
id, node_id, node_path, project_id, `name`, `type`, maintainer, priority, `method`,
|
||||
prerequisite, create_time, update_time, test_id, sort, num, other_test_name, review_status,
|
||||
tags, demand_id, demand_name
|
||||
tags, demand_id, demand_name, follow_people, `status`
|
||||
</sql>
|
||||
<sql id="Blob_Column_List">
|
||||
remark, steps
|
||||
|
@ -148,16 +150,16 @@
|
|||
prerequisite, create_time, update_time,
|
||||
test_id, sort, num,
|
||||
other_test_name, review_status, tags,
|
||||
demand_id, demand_name, remark,
|
||||
steps)
|
||||
demand_id, demand_name, follow_people,
|
||||
`status`, remark, steps)
|
||||
values (#{id,jdbcType=VARCHAR}, #{nodeId,jdbcType=VARCHAR}, #{nodePath,jdbcType=VARCHAR},
|
||||
#{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR},
|
||||
#{maintainer,jdbcType=VARCHAR}, #{priority,jdbcType=VARCHAR}, #{method,jdbcType=VARCHAR},
|
||||
#{prerequisite,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
|
||||
#{testId,jdbcType=VARCHAR}, #{sort,jdbcType=INTEGER}, #{num,jdbcType=INTEGER},
|
||||
#{otherTestName,jdbcType=VARCHAR}, #{reviewStatus,jdbcType=VARCHAR}, #{tags,jdbcType=VARCHAR},
|
||||
#{demandId,jdbcType=VARCHAR}, #{demandName,jdbcType=VARCHAR}, #{remark,jdbcType=LONGVARCHAR},
|
||||
#{steps,jdbcType=LONGVARCHAR})
|
||||
#{demandId,jdbcType=VARCHAR}, #{demandName,jdbcType=VARCHAR}, #{followPeople,jdbcType=VARCHAR},
|
||||
#{status,jdbcType=VARCHAR}, #{remark,jdbcType=LONGVARCHAR}, #{steps,jdbcType=LONGVARCHAR})
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestCaseWithBLOBs">
|
||||
insert into test_case
|
||||
|
@ -222,6 +224,12 @@
|
|||
<if test="demandName != null">
|
||||
demand_name,
|
||||
</if>
|
||||
<if test="followPeople != null">
|
||||
follow_people,
|
||||
</if>
|
||||
<if test="status != null">
|
||||
`status`,
|
||||
</if>
|
||||
<if test="remark != null">
|
||||
remark,
|
||||
</if>
|
||||
|
@ -290,6 +298,12 @@
|
|||
<if test="demandName != null">
|
||||
#{demandName,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="followPeople != null">
|
||||
#{followPeople,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="status != null">
|
||||
#{status,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="remark != null">
|
||||
#{remark,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
|
@ -367,6 +381,12 @@
|
|||
<if test="record.demandName != null">
|
||||
demand_name = #{record.demandName,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.followPeople != null">
|
||||
follow_people = #{record.followPeople,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.status != null">
|
||||
`status` = #{record.status,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.remark != null">
|
||||
remark = #{record.remark,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
|
@ -381,40 +401,12 @@
|
|||
<update id="updateByExampleWithBLOBs" parameterType="map">
|
||||
update test_case
|
||||
set id = #{record.id,jdbcType=VARCHAR},
|
||||
node_id = #{record.nodeId,jdbcType=VARCHAR},
|
||||
node_path = #{record.nodePath,jdbcType=VARCHAR},
|
||||
project_id = #{record.projectId,jdbcType=VARCHAR},
|
||||
`name` = #{record.name,jdbcType=VARCHAR},
|
||||
`type` = #{record.type,jdbcType=VARCHAR},
|
||||
maintainer = #{record.maintainer,jdbcType=VARCHAR},
|
||||
priority = #{record.priority,jdbcType=VARCHAR},
|
||||
`method` = #{record.method,jdbcType=VARCHAR},
|
||||
prerequisite = #{record.prerequisite,jdbcType=VARCHAR},
|
||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||
test_id = #{record.testId,jdbcType=VARCHAR},
|
||||
sort = #{record.sort,jdbcType=INTEGER},
|
||||
num = #{record.num,jdbcType=INTEGER},
|
||||
other_test_name = #{record.otherTestName,jdbcType=VARCHAR},
|
||||
review_status = #{record.reviewStatus,jdbcType=VARCHAR},
|
||||
tags = #{record.tags,jdbcType=VARCHAR},
|
||||
demand_id = #{record.demandId,jdbcType=VARCHAR},
|
||||
demand_name = #{record.demandName,jdbcType=VARCHAR},
|
||||
remark = #{record.remark,jdbcType=LONGVARCHAR},
|
||||
steps = #{record.steps,jdbcType=LONGVARCHAR}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByExample" parameterType="map">
|
||||
update test_case
|
||||
set id = #{record.id,jdbcType=VARCHAR},
|
||||
node_id = #{record.nodeId,jdbcType=VARCHAR},
|
||||
node_path = #{record.nodePath,jdbcType=VARCHAR},
|
||||
project_id = #{record.projectId,jdbcType=VARCHAR},
|
||||
`name` = #{record.name,jdbcType=VARCHAR},
|
||||
`type` = #{record.type,jdbcType=VARCHAR},
|
||||
maintainer = #{record.maintainer,jdbcType=VARCHAR},
|
||||
node_id = #{record.nodeId,jdbcType=VARCHAR},
|
||||
node_path = #{record.nodePath,jdbcType=VARCHAR},
|
||||
project_id = #{record.projectId,jdbcType=VARCHAR},
|
||||
`name` = #{record.name,jdbcType=VARCHAR},
|
||||
`type` = #{record.type,jdbcType=VARCHAR},
|
||||
maintainer = #{record.maintainer,jdbcType=VARCHAR},
|
||||
priority = #{record.priority,jdbcType=VARCHAR},
|
||||
`method` = #{record.method,jdbcType=VARCHAR},
|
||||
prerequisite = #{record.prerequisite,jdbcType=VARCHAR},
|
||||
|
@ -427,7 +419,39 @@
|
|||
review_status = #{record.reviewStatus,jdbcType=VARCHAR},
|
||||
tags = #{record.tags,jdbcType=VARCHAR},
|
||||
demand_id = #{record.demandId,jdbcType=VARCHAR},
|
||||
demand_name = #{record.demandName,jdbcType=VARCHAR}
|
||||
demand_name = #{record.demandName,jdbcType=VARCHAR},
|
||||
follow_people = #{record.followPeople,jdbcType=VARCHAR},
|
||||
`status` = #{record.status,jdbcType=VARCHAR},
|
||||
remark = #{record.remark,jdbcType=LONGVARCHAR},
|
||||
steps = #{record.steps,jdbcType=LONGVARCHAR}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
</update>
|
||||
<update id="updateByExample" parameterType="map">
|
||||
update test_case
|
||||
set id = #{record.id,jdbcType=VARCHAR},
|
||||
node_id = #{record.nodeId,jdbcType=VARCHAR},
|
||||
node_path = #{record.nodePath,jdbcType=VARCHAR},
|
||||
project_id = #{record.projectId,jdbcType=VARCHAR},
|
||||
`name` = #{record.name,jdbcType=VARCHAR},
|
||||
`type` = #{record.type,jdbcType=VARCHAR},
|
||||
maintainer = #{record.maintainer,jdbcType=VARCHAR},
|
||||
priority = #{record.priority,jdbcType=VARCHAR},
|
||||
`method` = #{record.method,jdbcType=VARCHAR},
|
||||
prerequisite = #{record.prerequisite,jdbcType=VARCHAR},
|
||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||
test_id = #{record.testId,jdbcType=VARCHAR},
|
||||
sort = #{record.sort,jdbcType=INTEGER},
|
||||
num = #{record.num,jdbcType=INTEGER},
|
||||
other_test_name = #{record.otherTestName,jdbcType=VARCHAR},
|
||||
review_status = #{record.reviewStatus,jdbcType=VARCHAR},
|
||||
tags = #{record.tags,jdbcType=VARCHAR},
|
||||
demand_id = #{record.demandId,jdbcType=VARCHAR},
|
||||
demand_name = #{record.demandName,jdbcType=VARCHAR},
|
||||
follow_people = #{record.followPeople,jdbcType=VARCHAR},
|
||||
`status` = #{record.status,jdbcType=VARCHAR}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
|
@ -492,6 +516,12 @@
|
|||
<if test="demandName != null">
|
||||
demand_name = #{demandName,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="followPeople != null">
|
||||
follow_people = #{followPeople,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="status != null">
|
||||
`status` = #{status,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="remark != null">
|
||||
remark = #{remark,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
|
@ -522,6 +552,8 @@
|
|||
tags = #{tags,jdbcType=VARCHAR},
|
||||
demand_id = #{demandId,jdbcType=VARCHAR},
|
||||
demand_name = #{demandName,jdbcType=VARCHAR},
|
||||
follow_people = #{followPeople,jdbcType=VARCHAR},
|
||||
`status` = #{status,jdbcType=VARCHAR},
|
||||
remark = #{remark,jdbcType=LONGVARCHAR},
|
||||
steps = #{steps,jdbcType=LONGVARCHAR}
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
|
@ -546,7 +578,9 @@
|
|||
review_status = #{reviewStatus,jdbcType=VARCHAR},
|
||||
tags = #{tags,jdbcType=VARCHAR},
|
||||
demand_id = #{demandId,jdbcType=VARCHAR},
|
||||
demand_name = #{demandName,jdbcType=VARCHAR}
|
||||
demand_name = #{demandName,jdbcType=VARCHAR},
|
||||
follow_people = #{followPeople,jdbcType=VARCHAR},
|
||||
`status` = #{status,jdbcType=VARCHAR}
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
</mapper>
|
|
@ -0,0 +1,16 @@
|
|||
package io.metersphere.commons.utils;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
public class RsaKey {
|
||||
|
||||
//公钥
|
||||
private String publicKey;
|
||||
|
||||
//私钥
|
||||
private String privateKey;
|
||||
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
package io.metersphere.commons.utils;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.security.*;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
public class RsaUtil {
|
||||
|
||||
public static final String CHARSET = "UTF-8";
|
||||
public static final String RSA_ALGORITHM = "RSA";
|
||||
|
||||
|
||||
/**
|
||||
* 创建RSA 公钥-私钥
|
||||
*/
|
||||
public static RsaKey createKeys() throws NoSuchAlgorithmException {
|
||||
return createKeys(1024);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建RSA 公钥-私钥
|
||||
*/
|
||||
public static RsaKey createKeys(int keySize) throws NoSuchAlgorithmException {
|
||||
//为RSA算法创建一个KeyPairGenerator对象
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
|
||||
|
||||
//初始化KeyPairGenerator对象,密钥长度
|
||||
kpg.initialize(keySize);
|
||||
//生成密匙对
|
||||
KeyPair keyPair = kpg.generateKeyPair();
|
||||
|
||||
//得到公钥
|
||||
Key publicKey = keyPair.getPublic();
|
||||
|
||||
String publicKeyStr = new String(Base64.encodeBase64(publicKey.getEncoded()));
|
||||
|
||||
//得到私钥
|
||||
Key privateKey = keyPair.getPrivate();
|
||||
String privateKeyStr = new String(Base64.encodeBase64(privateKey.getEncoded()));
|
||||
|
||||
RsaKey rsaKey = new RsaKey();
|
||||
rsaKey.setPublicKey(publicKeyStr);
|
||||
rsaKey.setPrivateKey(privateKeyStr);
|
||||
|
||||
return rsaKey;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 公钥加密
|
||||
*
|
||||
* @param originalText 原文
|
||||
* @param publicKey 公钥
|
||||
*/
|
||||
public static String publicEncrypt(String originalText, String publicKey) throws NoSuchAlgorithmException {
|
||||
RSAPublicKey rsaPublicKey = getPublicKey(publicKey);
|
||||
return publicEncrypt(originalText, rsaPublicKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 公钥解密
|
||||
*
|
||||
* @param cipherText 密文
|
||||
* @param publicKey 公钥
|
||||
*/
|
||||
public static String publicDecrypt(String cipherText, String publicKey) throws NoSuchAlgorithmException {
|
||||
RSAPublicKey rsaPublicKey = getPublicKey(publicKey);
|
||||
return publicDecrypt(cipherText, rsaPublicKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 私钥加密
|
||||
*
|
||||
* @param originalText 原文
|
||||
* @param privateKey 私钥
|
||||
*/
|
||||
public static String privateEncrypt(String originalText, String privateKey) throws NoSuchAlgorithmException {
|
||||
RSAPrivateKey rsaPrivateKey = getPrivateKey(privateKey);
|
||||
return privateEncrypt(originalText, rsaPrivateKey);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 私钥解密
|
||||
*
|
||||
* @param cipherText 密文
|
||||
* @param privateKey 私钥
|
||||
*/
|
||||
public static String privateDecrypt(String cipherText, String privateKey) throws NoSuchAlgorithmException {
|
||||
RSAPrivateKey rsaPrivateKey = getPrivateKey(privateKey);
|
||||
return privateDecrypt(cipherText, rsaPrivateKey);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 得到公钥
|
||||
*
|
||||
* @param publicKey 密钥字符串(经过base64编码)
|
||||
*/
|
||||
private static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException {
|
||||
//通过X509编码的Key指令获得公钥对象
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
|
||||
|
||||
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
|
||||
RSAPublicKey key = null;
|
||||
try {
|
||||
key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
|
||||
} catch (InvalidKeySpecException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 公钥加密
|
||||
*
|
||||
* @param originalText 原文
|
||||
* @param publicKey 公钥
|
||||
*/
|
||||
private static String publicEncrypt(String originalText, RSAPublicKey publicKey) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||
return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, originalText.getBytes(CHARSET), publicKey.getModulus().bitLength()));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("加密字符串[" + originalText + "]时遇到异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到私钥
|
||||
*
|
||||
* @param privateKey 密钥字符串(经过base64编码)
|
||||
*/
|
||||
private static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException {
|
||||
//通过PKCS#8编码的Key指令获得私钥对象
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
|
||||
|
||||
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
|
||||
RSAPrivateKey key = null;
|
||||
try {
|
||||
key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
|
||||
} catch (InvalidKeySpecException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 私钥解密
|
||||
*
|
||||
* @param cipherText 密文
|
||||
* @param privateKey 私钥
|
||||
*/
|
||||
|
||||
private static String privateDecrypt(String cipherText, RSAPrivateKey privateKey) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(cipherText), privateKey.getModulus().bitLength()), CHARSET);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("解密字符串[" + cipherText + "]时遇到异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String privateEncrypt(String originalText, RSAPrivateKey privateKey) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
|
||||
return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, originalText.getBytes(CHARSET), privateKey.getModulus().bitLength()));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("加密字符串[" + originalText + "]时遇到异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String publicDecrypt(String cipherText, RSAPublicKey publicKey) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
|
||||
cipher.init(Cipher.DECRYPT_MODE, publicKey);
|
||||
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(cipherText), publicKey.getModulus().bitLength()), CHARSET);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("解密字符串[" + cipherText + "]时遇到异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
|
||||
int maxBlock;
|
||||
if (opmode == Cipher.DECRYPT_MODE) {
|
||||
maxBlock = keySize / 8;
|
||||
} else {
|
||||
maxBlock = keySize / 8 - 11;
|
||||
}
|
||||
int offSet = 0;
|
||||
byte[] buff;
|
||||
int i = 0;
|
||||
try (
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream()
|
||||
) {
|
||||
while (datas.length > offSet) {
|
||||
if (datas.length - offSet > maxBlock) {
|
||||
buff = cipher.doFinal(datas, offSet, maxBlock);
|
||||
} else {
|
||||
buff = cipher.doFinal(datas, offSet, datas.length - offSet);
|
||||
}
|
||||
out.write(buff, 0, buff.length);
|
||||
i++;
|
||||
offSet = i * maxBlock;
|
||||
}
|
||||
return out.toByteArray();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时发生异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -46,6 +46,7 @@ public class ShiroUtils {
|
|||
|
||||
public static void ignoreCsrfFilter(Map<String, String> filterChainDefinitionMap) {
|
||||
filterChainDefinitionMap.put("/", "apikey, authc"); // 跳转到 / 不用校验 csrf
|
||||
filterChainDefinitionMap.put("/document", "apikey, authc"); // 跳转到 /document 不用校验 csrf
|
||||
}
|
||||
|
||||
public static Cookie getSessionIdCookie(){
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package io.metersphere.config;
|
||||
|
||||
import io.metersphere.commons.utils.RsaKey;
|
||||
import io.metersphere.commons.utils.RsaUtil;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
@Configuration
|
||||
public class RsaConfig {
|
||||
@Bean
|
||||
public RsaKey rsaKey() throws NoSuchAlgorithmException {
|
||||
return RsaUtil.createKeys();
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@ package io.metersphere.controller;
|
|||
|
||||
import io.metersphere.commons.constants.UserSource;
|
||||
import io.metersphere.commons.user.SessionUser;
|
||||
import io.metersphere.commons.utils.RsaKey;
|
||||
import io.metersphere.commons.utils.RsaUtil;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.controller.request.LoginRequest;
|
||||
import io.metersphere.service.BaseDisplayService;
|
||||
|
@ -23,6 +25,8 @@ public class LoginController {
|
|||
private UserService userService;
|
||||
@Resource
|
||||
private BaseDisplayService baseDisplayService;
|
||||
@Resource
|
||||
private RsaKey rsaKey;
|
||||
|
||||
@GetMapping(value = "/isLogin")
|
||||
public ResultHolder isLogin() {
|
||||
|
@ -33,7 +37,7 @@ public class LoginController {
|
|||
}
|
||||
return ResultHolder.success(user);
|
||||
}
|
||||
return ResultHolder.error("");
|
||||
return ResultHolder.error(rsaKey.getPublicKey());
|
||||
}
|
||||
|
||||
@PostMapping(value = "/signin")
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.github.pagehelper.PageHelper;
|
|||
import io.metersphere.api.service.ApiAutomationService;
|
||||
import io.metersphere.base.domain.Schedule;
|
||||
import io.metersphere.controller.request.QueryScheduleRequest;
|
||||
import io.metersphere.controller.request.ScheduleRequest;
|
||||
import io.metersphere.dto.ScheduleDao;
|
||||
import io.metersphere.service.ScheduleService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
@ -38,7 +39,7 @@ public class ScheduleController {
|
|||
}
|
||||
|
||||
@PostMapping(value = "/create")
|
||||
public void createSchedule(@RequestBody Schedule request) {
|
||||
public void createSchedule(@RequestBody ScheduleRequest request) {
|
||||
scheduleService.createSchedule(request);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,36 @@
|
|||
package io.metersphere.controller.request;
|
||||
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.RsaKey;
|
||||
import io.metersphere.commons.utils.RsaUtil;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class LoginRequest {
|
||||
private String username;
|
||||
private String password;
|
||||
private String authenticate;
|
||||
|
||||
|
||||
public String getUsername() {
|
||||
try {
|
||||
RsaKey rsaKey = CommonBeanFactory.getBean(RsaKey.class);
|
||||
return RsaUtil.privateDecrypt(username, rsaKey.getPrivateKey());
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
return username;
|
||||
}
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
try {
|
||||
RsaKey rsaKey = CommonBeanFactory.getBean(RsaKey.class);
|
||||
return RsaUtil.privateDecrypt(password, rsaKey.getPrivateKey());
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
return password;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package io.metersphere.controller.request;
|
||||
|
||||
import io.metersphere.base.domain.Schedule;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author song.tianyang
|
||||
* @Date 2021/3/12 12:57 下午
|
||||
* @Description
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class ScheduleRequest extends Schedule {
|
||||
|
||||
//定时任务来源: 测试计划/测试场景
|
||||
private String scheduleFrom;
|
||||
|
||||
private String projectId;
|
||||
|
||||
private String moduleId;
|
||||
|
||||
private String modulePath;
|
||||
|
||||
private String modeId;
|
||||
|
||||
}
|
|
@ -10,6 +10,7 @@ import io.metersphere.commons.utils.PageUtils;
|
|||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.controller.request.QueryScheduleRequest;
|
||||
import io.metersphere.controller.request.ScheduleRequest;
|
||||
import io.metersphere.dto.DashboardTestDTO;
|
||||
import io.metersphere.dto.LoadTestDTO;
|
||||
import io.metersphere.dto.ScheduleDao;
|
||||
|
@ -175,7 +176,7 @@ public class PerformanceTestController {
|
|||
}
|
||||
|
||||
@PostMapping(value = "/schedule/create")
|
||||
public void createSchedule(@RequestBody Schedule request) {
|
||||
public void createSchedule(@RequestBody ScheduleRequest request) {
|
||||
performanceTestService.createSchedule(request);
|
||||
}
|
||||
|
||||
|
|
|
@ -103,12 +103,18 @@ public class DockerTestEngine extends AbstractEngine {
|
|||
startTestRequest.setEnv(env);
|
||||
|
||||
String uri = String.format(BASE_URL + "/jmeter/container/start", nodeIp, port);
|
||||
ResultHolder result = restTemplate.postForObject(uri, startTestRequest, ResultHolder.class);
|
||||
if (result == null) {
|
||||
MSException.throwException(Translator.get("start_engine_fail"));
|
||||
}
|
||||
if (!result.isSuccess()) {
|
||||
MSException.throwException(result.getMessage());
|
||||
try {
|
||||
ResultHolder result = restTemplate.postForObject(uri, startTestRequest, ResultHolder.class);
|
||||
if (result == null) {
|
||||
MSException.throwException(Translator.get("start_engine_fail"));
|
||||
}
|
||||
if (!result.isSuccess()) {
|
||||
MSException.throwException(result.getMessage());
|
||||
}
|
||||
} catch (MSException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
MSException.throwException("Please check node-controller status.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import io.metersphere.commons.utils.SessionUtils;
|
|||
import io.metersphere.config.KafkaProperties;
|
||||
import io.metersphere.controller.request.OrderRequest;
|
||||
import io.metersphere.controller.request.QueryScheduleRequest;
|
||||
import io.metersphere.controller.request.ScheduleRequest;
|
||||
import io.metersphere.dto.DashboardTestDTO;
|
||||
import io.metersphere.dto.LoadTestDTO;
|
||||
import io.metersphere.dto.ScheduleDao;
|
||||
|
@ -465,12 +466,12 @@ public class PerformanceTestService {
|
|||
addOrUpdatePerformanceTestCronJob(request);
|
||||
}
|
||||
|
||||
public void createSchedule(Schedule request) {
|
||||
public void createSchedule(ScheduleRequest request) {
|
||||
scheduleService.addSchedule(buildPerformanceTestSchedule(request));
|
||||
addOrUpdatePerformanceTestCronJob(request);
|
||||
}
|
||||
|
||||
private Schedule buildPerformanceTestSchedule(Schedule request) {
|
||||
private Schedule buildPerformanceTestSchedule(ScheduleRequest request) {
|
||||
Schedule schedule = scheduleService.buildApiTestSchedule(request);
|
||||
schedule.setJob(PerformanceTestJob.class.getName());
|
||||
schedule.setGroup(ScheduleGroup.PERFORMANCE_TEST.name());
|
||||
|
|
|
@ -17,6 +17,7 @@ import io.metersphere.commons.utils.ServiceUtils;
|
|||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.controller.request.OrderRequest;
|
||||
import io.metersphere.controller.request.QueryScheduleRequest;
|
||||
import io.metersphere.controller.request.ScheduleRequest;
|
||||
import io.metersphere.dto.ScheduleDao;
|
||||
import io.metersphere.job.sechedule.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -143,7 +144,7 @@ public class ScheduleService {
|
|||
});
|
||||
}
|
||||
|
||||
public Schedule buildApiTestSchedule(Schedule request) {
|
||||
public Schedule buildApiTestSchedule(ScheduleRequest request) {
|
||||
Schedule schedule = new Schedule();
|
||||
schedule.setResourceId(request.getResourceId());
|
||||
schedule.setEnable(true);
|
||||
|
@ -218,7 +219,7 @@ public class ScheduleService {
|
|||
return runningTaskInfoList;
|
||||
}
|
||||
|
||||
public void createSchedule(Schedule request) {
|
||||
public void createSchedule(ScheduleRequest request) {
|
||||
Schedule schedule = this.buildApiTestSchedule(request);
|
||||
schedule.setJob(ApiScenarioTestJob.class.getName());
|
||||
|
||||
|
|
|
@ -190,4 +190,9 @@ public class TestCaseController {
|
|||
.body(bytes);
|
||||
}
|
||||
|
||||
@PostMapping("/save")
|
||||
public TestCaseWithBLOBs saveTestCase(@RequestBody TestCaseWithBLOBs testCaseWithBLOBs) {
|
||||
return testCaseService.addTestCase(testCaseWithBLOBs);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ public class TestCaseService {
|
|||
@Resource
|
||||
TestCaseFileMapper testCaseFileMapper;
|
||||
|
||||
private TestCaseWithBLOBs addTestCase(TestCaseWithBLOBs testCase) {
|
||||
public TestCaseWithBLOBs addTestCase(TestCaseWithBLOBs testCase) {
|
||||
testCase.setName(testCase.getName());
|
||||
checkTestCaseExist(testCase);
|
||||
testCase.setId(UUID.randomUUID().toString());
|
||||
|
@ -102,6 +102,7 @@ public class TestCaseService {
|
|||
testCase.setReviewStatus(TestCaseReviewStatus.Prepare.name());
|
||||
testCase.setDemandId(testCase.getDemandId());
|
||||
testCase.setDemandName(testCase.getDemandName());
|
||||
|
||||
testCaseMapper.insert(testCase);
|
||||
return testCase;
|
||||
}
|
||||
|
@ -703,4 +704,5 @@ public class TestCaseService {
|
|||
request.setSelectFields(selectFields);
|
||||
return extTestCaseMapper.list(request);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit d2fc4b42117be97c679b4d15d6f979923e598f7f
|
||||
Subproject commit efd6af73b7c5cc53cd4515772000bc1436c49837
|
|
@ -9,7 +9,48 @@ CREATE TABLE IF NOT EXISTS `user_header`
|
|||
primary key (id)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4;
|
||||
|
||||
-- create table test_case_review_api_case
|
||||
create table test_case_review_api_case
|
||||
(
|
||||
id varchar(50) not null,
|
||||
test_case_review_id varchar(50) null,
|
||||
api_case_id varchar(50) null,
|
||||
status varchar(50) null,
|
||||
environment_id varchar(50) null,
|
||||
create_time bigint(13) null,
|
||||
update_time bigint(13) null,
|
||||
primary key (id)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4;
|
||||
-- create table test_case_review_scenario
|
||||
create table test_case_review_scenario
|
||||
(
|
||||
id varchar(50) not null,
|
||||
test_case_review_id varchar(50) null,
|
||||
api_scenario_id varchar(50) null,
|
||||
status varchar(50) null,
|
||||
environment varchar(50) null,
|
||||
create_time bigint(13) null,
|
||||
update_time bigint(13) null,
|
||||
pass_rate varchar(100) null,
|
||||
last_result varchar(100) null,
|
||||
report_id varchar(50) null,
|
||||
primary key (id)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4;
|
||||
-- create table test_case_review_load
|
||||
create table test_case_review_load
|
||||
(
|
||||
id varchar(50) not null,
|
||||
test_case_review_id varchar(50) null,
|
||||
load_case_id varchar(50) null,
|
||||
status varchar(50) null,
|
||||
create_time bigint(13) null,
|
||||
update_time bigint(13) null,
|
||||
load_report_id varchar(50) null,
|
||||
primary key (id)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4;
|
||||
-- test_resource_pool add column
|
||||
ALTER TABLE test_resource_pool ADD heap VARCHAR(200) NULL;
|
||||
ALTER TABLE test_resource_pool ADD gc_algo VARCHAR(200) NULL;
|
||||
|
@ -37,14 +78,19 @@ alter table test_case
|
|||
|
||||
alter table test_case
|
||||
add demand_name varchar(999) null;
|
||||
alter table test_case
|
||||
add follow_people varchar(100) null;
|
||||
-- test_case_review add column
|
||||
ALTER TABLE test_case_review ADD tags VARCHAR(2000) NULL;
|
||||
ALTER TABLE test_case_review
|
||||
ADD tags VARCHAR(2000) NULL;
|
||||
|
||||
-- alter test_plan_api_scenario
|
||||
alter table test_plan_api_scenario change environment_id environment longtext null comment 'Relevance environment';
|
||||
alter table test_plan_api_scenario
|
||||
change environment_id environment longtext null comment 'Relevance environment';
|
||||
|
||||
-- file add sort column
|
||||
alter table file_metadata add sort int default 0;
|
||||
alter table file_metadata
|
||||
add sort int default 0;
|
||||
|
||||
-- add Original state
|
||||
alter table api_definition add original_state varchar(64);
|
||||
|
|
|
@ -49,7 +49,8 @@
|
|||
"xml-js": "^1.6.11",
|
||||
"yan-progress": "^1.0.3",
|
||||
"jsonpath": "^1.1.0",
|
||||
"vue-minder-editor-plus": "^1.0.14"
|
||||
"vue-minder-editor-plus": "^1.0.16",
|
||||
"jsencrypt": "^3.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "^4.1.0",
|
||||
|
|
|
@ -68,12 +68,6 @@
|
|||
:total="total"/>
|
||||
</el-card>
|
||||
</ms-main-container>
|
||||
|
||||
<el-drawer :visible.sync="debugVisible" :destroy-on-close="true" direction="ltr" :withHeader="false"
|
||||
:title="$t('test_track.plan_view.test_result')" :modal="false" size="90%">
|
||||
<ms-api-report-detail :report-id="reportId" :currentProjectId="currentProjectId" :info-db="true"
|
||||
@refresh="search"/>
|
||||
</el-drawer>
|
||||
</ms-container>
|
||||
</template>
|
||||
|
||||
|
@ -89,14 +83,13 @@ import ReportTriggerModeItem from "../../../common/tableItem/ReportTriggerModeIt
|
|||
import {REPORT_CONFIGS} from "../../../common/components/search/search-components";
|
||||
import {ApiEvent, LIST_CHANGE} from "@/business/components/common/head/ListEvent";
|
||||
import ShowMoreBtn from "../../../track/case/components/ShowMoreBtn";
|
||||
import MsApiReportDetail from "./ApiReportDetail";
|
||||
import {_filter, _sort} from "@/common/js/tableUtils";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ReportTriggerModeItem,
|
||||
MsTableOperatorButton,
|
||||
MsApiReportStatus, MsMainContainer, MsContainer, MsTableHeader, MsTablePagination, ShowMoreBtn, MsApiReportDetail
|
||||
MsApiReportStatus, MsMainContainer, MsContainer, MsTableHeader, MsTablePagination, ShowMoreBtn
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -167,7 +160,10 @@ export default {
|
|||
handleView(report) {
|
||||
this.reportId = report.id;
|
||||
this.currentProjectId = report.projectId;
|
||||
this.debugVisible = true;
|
||||
this.$router.push({
|
||||
path: 'report/view/' + report.id,
|
||||
})
|
||||
|
||||
},
|
||||
handleDelete(report) {
|
||||
this.$alert(this.$t('api_report.delete_confirm') + report.name + "?", '', {
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<template>
|
||||
<ms-api-report :report-id="reportId"></ms-api-report>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsApiReport from "@/business/components/api/automation/report/ApiReportDetail";
|
||||
export default {
|
||||
name: "ApiReportView",
|
||||
components: {MsApiReport},
|
||||
computed: {
|
||||
reportId:function (){
|
||||
return this.$route.params.reportId
|
||||
}
|
||||
},
|
||||
created() {
|
||||
console.log(this.reportId)
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -31,10 +31,10 @@
|
|||
</el-tooltip>
|
||||
<slot name="button"></slot>
|
||||
<el-tooltip content="Copy" placement="top">
|
||||
<el-button size="mini" icon="el-icon-copy-document" circle @click="copyRow" :disabled="data.referenced==='REF' || data.disabled"/>
|
||||
<el-button size="mini" icon="el-icon-copy-document" circle @click="copyRow" :disabled="data && data.disabled"/>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="$t('commons.remove')" placement="top">
|
||||
<el-button size="mini" icon="el-icon-delete" type="danger" circle @click="remove" :disabled="data.referenced==='REF' || data.disabled"/>
|
||||
<el-button size="mini" icon="el-icon-delete" type="danger" circle @click="remove" :disabled="data && data.disabled"/>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
:title="displayTitle">
|
||||
|
||||
<template v-slot:behindHeaderLeft>
|
||||
<el-tag size="mini" style="margin-left: 20px" v-if="request.referenced==='Deleted'" type="danger">{{$t('api_test.automation.reference_deleted')}}</el-tag>
|
||||
<el-tag size="mini" style="margin-left: 20px" v-if="request.referenced==='Copy'">{{ $t('commons.copy') }}</el-tag>
|
||||
<el-tag size="mini" style="margin-left: 20px" v-if="request.referenced ==='REF'">{{ $t('api_test.scenario.reference') }}</el-tag>
|
||||
<span style="margin-left: 20px;">{{getProjectName(request.projectId)}}</span>
|
||||
<el-tag size="mini" class="ms-tag" v-if="request.referenced==='Deleted'" type="danger">{{$t('api_test.automation.reference_deleted')}}</el-tag>
|
||||
<el-tag size="mini" class="ms-tag" v-if="request.referenced==='Copy'">{{ $t('commons.copy') }}</el-tag>
|
||||
<el-tag size="mini" class="ms-tag" v-if="request.referenced ==='REF'">{{ $t('api_test.scenario.reference') }}</el-tag>
|
||||
<span class="ms-tag">{{getProjectName(request.projectId)}}</span>
|
||||
<ms-run :debug="true" :reportId="reportId" :run-data="runData" :env-map="envMap"
|
||||
@runRefresh="runRefresh" ref="runTest"/>
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
|||
|
||||
<template v-slot:button>
|
||||
<el-tooltip :content="$t('api_test.run')" placement="top">
|
||||
<el-button @click="run" icon="el-icon-video-play" style="background-color: #409EFF;color: white;" size="mini" circle/>
|
||||
<el-button @click="run" icon="el-icon-video-play" class="ms-btn" size="mini" circle/>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
|||
<api-response-component :currentProtocol="request.protocol" :result="request.requestResult" v-else/>
|
||||
|
||||
<!-- 保存操作 -->
|
||||
<el-button type="primary" size="small" style="margin: 20px; float: right" @click="saveTestCase(item)"
|
||||
<el-button type="primary" size="small" class="ms-btn-flot" @click="saveTestCase(item)"
|
||||
v-if="!request.referenced">
|
||||
{{ $t('commons.save') }}
|
||||
</el-button>
|
||||
|
@ -67,7 +67,7 @@
|
|||
import MsApiRequestForm from "../../../definition/components/request/http/ApiHttpRequestForm";
|
||||
import MsRequestResultTail from "../../../definition/components/response/RequestResultTail";
|
||||
import MsRun from "../../../definition/components/Run";
|
||||
import {getUUID,getCurrentProjectID} from "@/common/js/utils";
|
||||
import {getUUID, getCurrentProjectID} from "@/common/js/utils";
|
||||
import ApiBaseComponent from "../common/ApiBaseComponent";
|
||||
import ApiResponseComponent from "./ApiResponseComponent";
|
||||
import CustomizeReqInfo from "@/business/components/api/automation/scenario/common/CustomizeReqInfo";
|
||||
|
@ -216,7 +216,7 @@
|
|||
}
|
||||
this.request.requestResult = requestResult;
|
||||
this.request.id = response.data.id;
|
||||
this.request.disabled = true;
|
||||
//this.request.disabled = true;
|
||||
if (!this.request.projectId) {
|
||||
this.request.projectId = response.data.projectId;
|
||||
}
|
||||
|
@ -333,4 +333,18 @@
|
|||
content: "";
|
||||
|
||||
}
|
||||
|
||||
.ms-btn {
|
||||
background-color: #409EFF;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.ms-btn-flot {
|
||||
margin: 20px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.ms-tag {
|
||||
margin-left: 20px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
:title="$t('api_test.automation.scenario_import')">
|
||||
|
||||
<template v-slot:behindHeaderLeft>
|
||||
<el-tag size="mini" style="margin-left: 20px" v-if="scenario.referenced==='Deleted'" type="danger">{{$t('api_test.automation.reference_deleted')}}</el-tag>
|
||||
<el-tag size="mini" style="margin-left: 20px" v-if="scenario.referenced==='Copy'">{{ $t('commons.copy') }}</el-tag>
|
||||
<el-tag size="mini" style="margin-left: 20px" v-if="scenario.referenced==='REF'">{{ $t('api_test.scenario.reference') }}</el-tag>
|
||||
<el-tag size="mini" class="ms-tag" v-if="scenario.referenced==='Deleted'" type="danger">{{$t('api_test.automation.reference_deleted')}}</el-tag>
|
||||
<el-tag size="mini" class="ms-tag" v-if="scenario.referenced==='Copy'">{{ $t('commons.copy') }}</el-tag>
|
||||
<el-tag size="mini" class="ms-tag" v-if="scenario.referenced==='REF'">{{ $t('api_test.scenario.reference') }}</el-tag>
|
||||
|
||||
<span style="margin-left: 20px;">{{getProjectName(scenario.projectId)}}</span>
|
||||
<span class="ms-tag">{{getProjectName(scenario.projectId)}}</span>
|
||||
</template>
|
||||
|
||||
</api-base-component>
|
||||
|
@ -58,7 +58,7 @@
|
|||
if (this.scenario.hashTree) {
|
||||
this.setDisabled(this.scenario.hashTree);
|
||||
}
|
||||
this.scenario.disabled = true;
|
||||
//this.scenario.disabled = true;
|
||||
this.scenario.name = response.data.name;
|
||||
if (!this.scenario.projectId) {
|
||||
this.scenario.projectId = response.data.projectId;
|
||||
|
@ -128,7 +128,7 @@
|
|||
}
|
||||
},
|
||||
getProjectName(id) {
|
||||
const project = this.projectList.find(p => p.id === id) ;
|
||||
const project = this.projectList.find(p => p.id === id);
|
||||
return project ? project.name : "";
|
||||
}
|
||||
}
|
||||
|
@ -145,4 +145,7 @@
|
|||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.ms-tag {
|
||||
margin-left: 20px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
<el-input draggable size="small" v-model="controller.variable" style="width: 20%" :placeholder="$t('api_test.request.condition_variable')"/>
|
||||
|
||||
<el-select v-model="controller.operator" :placeholder="$t('commons.please_select')" size="small"
|
||||
@change="change" style="width: 10%;margin-left: 10px">
|
||||
@change="change" class="ms-select">
|
||||
<el-option v-for="o in operators" :key="o.value" :label="$t(o.label)" :value="o.value"/>
|
||||
</el-select>
|
||||
|
||||
<el-input draggable size="small" v-model="controller.value" :placeholder="$t('api_test.value')" v-if="!hasEmptyOperator" style="width: 20%;margin-left: 20px"/>
|
||||
<el-input draggable size="small" v-model="controller.value" :placeholder="$t('api_test.value')" v-if="!hasEmptyOperator" class="ms-btn"/>
|
||||
</template>
|
||||
|
||||
</api-base-component>
|
||||
|
@ -26,6 +26,7 @@
|
|||
|
||||
<script>
|
||||
import ApiBaseComponent from "../common/ApiBaseComponent";
|
||||
|
||||
export default {
|
||||
name: "MsIfController",
|
||||
components: {ApiBaseComponent},
|
||||
|
@ -98,4 +99,13 @@
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ms-btn {
|
||||
width: 20%;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.ms-select {
|
||||
width: 10%;
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -69,7 +69,6 @@
|
|||
</div>
|
||||
<div v-else draggable>
|
||||
<el-input size="small" v-model="controller.whileController.variable" style="width: 20%" :placeholder="$t('api_test.request.condition_variable')"/>
|
||||
|
||||
<el-select v-model="controller.whileController.operator" :placeholder="$t('commons.please_select')" size="small"
|
||||
@change="change" style="width: 10%;margin-left: 10px">
|
||||
<el-option v-for="o in operators" :key="o.value" :label="$t(o.label)" :value="o.value"/>
|
||||
|
@ -79,18 +78,6 @@
|
|||
<el-input-number size="small" v-model="controller.whileController.timeout" :placeholder="$t('commons.millisecond')" :max="1000*10000000" :min="3000" :step="1000"/>
|
||||
<span class="ms-span ms-radio">ms</span>
|
||||
</div>
|
||||
<!--<p class="tip">{{$t('api_test.definition.request.res_param')}} </p>-->
|
||||
<!--<div>-->
|
||||
<!--<el-tabs v-model="activeName" closable class="ms-tabs">-->
|
||||
<!--<el-tab-pane :label="item.name" :name="item.name" v-for="(item,index) in requestResult.scenarios" :key="index">-->
|
||||
<!--<div v-for="(result,i) in item.requestResults" :key="i" style="margin-bottom: 5px">-->
|
||||
<!--<api-response-component :result="result"/>-->
|
||||
<!--</div>-->
|
||||
<!--</el-tab-pane>-->
|
||||
<!--</el-tabs>-->
|
||||
|
||||
<!--</div>-->
|
||||
|
||||
</api-base-component>
|
||||
|
||||
</div>
|
||||
|
@ -344,14 +331,6 @@ export default {
|
|||
font-weight: normal;
|
||||
}
|
||||
|
||||
.tip {
|
||||
padding: 3px 5px;
|
||||
font-size: 16px;
|
||||
border-radius: 4px;
|
||||
border-left: 4px solid #783887;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.icon.is-active {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
|
|
@ -325,7 +325,7 @@ export default {
|
|||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
screenHeight: document.documentElement.clientHeight - 270,//屏幕高度,
|
||||
screenHeight: document.documentElement.clientHeight - 310,//屏幕高度,
|
||||
environmentId: undefined,
|
||||
selectDataCounts: 0,
|
||||
}
|
||||
|
|
|
@ -63,6 +63,12 @@ export default {
|
|||
name: "ApiReportList",
|
||||
component: () => import('@/business/components/api/automation/report/ApiReportList'),
|
||||
},
|
||||
{
|
||||
path:"automation/report/view/:reportId",
|
||||
name:"ApiReportView",
|
||||
component: () => import('@/business/components/api/automation/report/ApiReportView'),
|
||||
|
||||
},
|
||||
{
|
||||
path: 'monitor/view',
|
||||
name: 'ApiMonitor',
|
||||
|
|
|
@ -132,6 +132,7 @@ import MsChart from "@/business/components/common/chart/MsChart";
|
|||
import {findThreadGroup} from "@/business/components/performance/test/model/ThreadGroup";
|
||||
|
||||
const HANDLER = "handler";
|
||||
const THREAD_GROUP_TYPE = "tgType";
|
||||
const TARGET_LEVEL = "TargetLevel";
|
||||
const RAMP_UP = "RampUp";
|
||||
const STEPS = "Steps";
|
||||
|
@ -225,6 +226,9 @@ export default {
|
|||
case HANDLER:
|
||||
this.threadGroups[i].handler = item.value;
|
||||
break;
|
||||
case THREAD_GROUP_TYPE:
|
||||
this.threadGroups[i].tgType = item.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -360,7 +364,7 @@ export default {
|
|||
if (j === 0) {
|
||||
seriesData.data.push([0, 0]);
|
||||
}
|
||||
if (j > tg.rampUpTime) {
|
||||
if (j >= tg.rampUpTime) {
|
||||
xAxis.push(tg.duration);
|
||||
|
||||
seriesData.data.push([j, tg.threadNumber]);
|
||||
|
@ -471,7 +475,7 @@ export default {
|
|||
if (i === 0) {
|
||||
handler.options.series[0].data.push([0, 0]);
|
||||
}
|
||||
if (i > handler.rampUpTime) {
|
||||
if (i >= handler.rampUpTime) {
|
||||
handler.options.xAxis.data.push(handler.duration);
|
||||
|
||||
handler.options.series[0].data.push([i, handler.threadNumber]);
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
:disabled="isReadOnly"
|
||||
:min="1"
|
||||
v-model="threadGroup.rampUpTime"
|
||||
@change="calculateChart(threadGroup)"
|
||||
size="mini"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('load_test.ramp_up_time_seconds')"/>
|
||||
|
@ -402,7 +403,7 @@ export default {
|
|||
if (j === 0) {
|
||||
seriesData.data.push([0, 0]);
|
||||
}
|
||||
if (j > tg.rampUpTime) {
|
||||
if (j >= tg.rampUpTime) {
|
||||
xAxis.push(tg.duration);
|
||||
|
||||
seriesData.data.push([j, tg.threadNumber]);
|
||||
|
@ -519,7 +520,7 @@ export default {
|
|||
if (i === 0) {
|
||||
handler.options.series[0].data.push([0, 0]);
|
||||
}
|
||||
if (i > handler.rampUpTime) {
|
||||
if (i >= handler.rampUpTime) {
|
||||
handler.options.xAxis.data.push(handler.duration);
|
||||
|
||||
handler.options.series[0].data.push([i, handler.threadNumber]);
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
@refreshTable="refresh"
|
||||
@setTreeNodes="setTreeNodes"
|
||||
@exportTestCase="exportTestCase"
|
||||
@saveAsEdit="editTestCase"
|
||||
:type="'edit'"
|
||||
ref="nodeTree"/>
|
||||
ref="nodeTree"
|
||||
/>
|
||||
</ms-aside-container>
|
||||
|
||||
<ms-main-container>
|
||||
|
@ -161,7 +163,6 @@ export default {
|
|||
},
|
||||
isRedirectEdit: function () {
|
||||
let redirectParam = this.$route.params.dataSelectRange;
|
||||
this.checkRedirectEditPage(redirectParam);
|
||||
return redirectParam;
|
||||
}
|
||||
},
|
||||
|
@ -191,29 +192,6 @@ export default {
|
|||
this.redirectFlag = "none";
|
||||
}
|
||||
},
|
||||
checkRedirectEditPage(redirectParam) {
|
||||
if (redirectParam != null) {
|
||||
let selectParamArr = redirectParam.split("edit:");
|
||||
if (selectParamArr.length == 2) {
|
||||
let scenarioId = selectParamArr[1];
|
||||
let projectId = getCurrentProjectID();
|
||||
//查找单条数据,跳转修改页面
|
||||
/* let url = "/api/automation/list/" + 1 + "/" + 1;
|
||||
this.$post(url, {id: scenarioId, projectId: projectId}, response => {
|
||||
let data = response.data;
|
||||
if (data != null) {
|
||||
//如果树未加载
|
||||
if (JSON.stringify(this.moduleOptions) === '{}') {
|
||||
this.$refs.nodeTree.list();
|
||||
}
|
||||
let row = data.listObject[0];
|
||||
row.tags = JSON.parse(row.tags);
|
||||
this.editScenario(row);
|
||||
}
|
||||
});*/
|
||||
}
|
||||
}
|
||||
},
|
||||
addTab(tab) {
|
||||
if (!getCurrentProjectID()) {
|
||||
this.$warning(this.$t('commons.check_project_tip'));
|
||||
|
@ -301,25 +279,17 @@ export default {
|
|||
return;
|
||||
}
|
||||
this.addTab({name: 'edit', testCaseInfo: testCase});
|
||||
|
||||
|
||||
},
|
||||
|
||||
copyTestCase(testCase) {
|
||||
this.type="copy"
|
||||
this.testCaseReadOnly = false;
|
||||
let item = {};
|
||||
testCase.isCopy = true;
|
||||
this.addTab({name: 'edit', testCaseInfo: testCase});
|
||||
|
||||
/*
|
||||
this.$refs.testCaseEditDialog.open(item);
|
||||
*/
|
||||
},
|
||||
showTestCaseDetail(testCase) {
|
||||
this.testCaseReadOnly = true;
|
||||
/*
|
||||
this.$refs.testCaseEditDialog.open(testCase);
|
||||
*/
|
||||
},
|
||||
refresh() {
|
||||
this.selectNodeIds = [];
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<el-input v-model="testCaseForm.name" autocomplete="off" :placeholder="$t('commons.name')"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('api_test.automation.scenario.principal')" prop="principal">
|
||||
<el-form-item :label="$t('api_test.automation.scenario.principal')" prop="maintainer">
|
||||
<el-select v-model="testCaseForm.maintainer"
|
||||
:placeholder="$t('api_test.automation.scenario.principal')" filterable size="small"
|
||||
style="width: 100%">
|
||||
|
@ -61,59 +61,87 @@
|
|||
import {getCurrentProjectID, getCurrentUser, getUUID} from "@/common/js/utils";
|
||||
import {WORKSPACE_ID} from "@/common/js/constants";
|
||||
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
|
||||
import {buildNodePath} from "@/business/components/api/definition/model/NodeTree";
|
||||
|
||||
export default {
|
||||
name: "TestCaseCreate",
|
||||
name: "TestCaseCreate",
|
||||
components: {MsDialogFooter},
|
||||
data(){
|
||||
return{
|
||||
testCaseForm:{},
|
||||
visible: false,
|
||||
currentModule: {},
|
||||
userOptions: [],
|
||||
rule: {
|
||||
name: [
|
||||
{required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'},
|
||||
{max: 100, message: this.$t('test_track.length_less_than') + '100', trigger: 'blur'}
|
||||
],
|
||||
principal: [{
|
||||
required: true,
|
||||
message: this.$t('api_test.automation.scenario.select_principal'),
|
||||
trigger: 'change'
|
||||
}],
|
||||
},
|
||||
}
|
||||
data() {
|
||||
return {
|
||||
testCaseForm: {},
|
||||
visible: false,
|
||||
currentModule: {},
|
||||
userOptions: [],
|
||||
rule: {
|
||||
name: [
|
||||
{required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'},
|
||||
{max: 100, message: this.$t('test_track.length_less_than') + '100', trigger: 'blur'}
|
||||
],
|
||||
maintainer: [{
|
||||
required: true,
|
||||
message: this.$t('api_test.automation.scenario.select_principal'),
|
||||
trigger: 'change'
|
||||
}],
|
||||
|
||||
|
||||
},
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
saveTestCase(){
|
||||
props: {
|
||||
treeNodes: {
|
||||
type: Array
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
treeNodes() {
|
||||
this.getModuleOptions();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
saveTestCase(saveAs) {
|
||||
this.$refs['testCaseForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
let path = "/api/automation/create";
|
||||
this.setParameter();
|
||||
/* this.$fileUpload(path, null, [], this.scenarioForm, () => {
|
||||
let path = "/test/case/save";
|
||||
this.testCaseForm.projectId = getCurrentProjectID();
|
||||
this.testCaseForm.type = "";
|
||||
this.testCaseForm.priority = "P0";
|
||||
this.testCaseForm.method = "manual";
|
||||
if(this.currentModule!==undefined){
|
||||
this.testCaseForm.nodePath = this.currentModule.path;
|
||||
this.testCaseForm.nodeId = this.currentModule.id;
|
||||
}else{
|
||||
this.testCaseForm.nodePath="/全部用例"
|
||||
this.testCaseForm.nodeId="root"
|
||||
}
|
||||
this.result = this.$post(path, this.testCaseForm, response => {
|
||||
this.testCaseForm.id=response.data.id
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.visible = false;
|
||||
if (saveAs) {
|
||||
this.scenarioForm.request = JSON.stringify(this.scenarioForm.request);
|
||||
this.$emit('saveAsEdit', this.scenarioForm);
|
||||
this.$emit('saveAsEdit', this.testCaseForm);
|
||||
} else {
|
||||
this.$emit('refresh');
|
||||
}
|
||||
});*/
|
||||
})
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
},
|
||||
setParameter() {
|
||||
this.scenarioForm.projectId = getCurrentProjectID();
|
||||
this.scenarioForm.id = getUUID().substring(0, 8);
|
||||
this.scenarioForm.protocol = this.currentProtocol;
|
||||
|
||||
if (this.currentModule && this.currentModule.id != "root") {
|
||||
this.scenarioForm.modulePath = this.currentModule.method !== undefined ? this.currentModule.method : null;
|
||||
this.scenarioForm.apiScenarioModuleId = this.currentModule.id;
|
||||
getModuleOptions() {
|
||||
let moduleOptions = [];
|
||||
this.treeNodes.forEach(node => {
|
||||
buildNodePath(node, {path: ''}, moduleOptions);
|
||||
});
|
||||
if(this.currentModule!==undefined){
|
||||
moduleOptions.forEach(item => {
|
||||
if (this.currentModule.id === item.id) {
|
||||
this.currentModule.path = item.path;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
getMaintainerOptions() {
|
||||
let workspaceId = localStorage.getItem(WORKSPACE_ID);
|
||||
this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {
|
||||
|
@ -121,10 +149,11 @@ name: "TestCaseCreate",
|
|||
});
|
||||
},
|
||||
open(currentModule) {
|
||||
this.scenarioForm = {principal: getCurrentUser().id};
|
||||
this.testCaseForm = {maintainer: getCurrentUser().id};
|
||||
this.currentModule = currentModule;
|
||||
this.getMaintainerOptions();
|
||||
this.visible = true;
|
||||
this.getModuleOptions()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,15 +48,24 @@
|
|||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-form-item label="状态" :label-width="formLabelWidth" prop="reviewStatus">
|
||||
<el-select size="small" v-model="form.reviewStatus" class="ms-case-input">
|
||||
<el-option v-for="item in options" :key="item.id" :label="item.label" :value="item.id"/>
|
||||
<el-form-item label="状态" :label-width="formLabelWidth" prop="status">
|
||||
<el-select size="small" v-model="form.status" class="ms-case-input">
|
||||
<el-option v-for="item in statuOptions" :key="item.id" :label="item.label" :value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<el-col :span="7">
|
||||
<el-form-item label="评审状态" :label-width="formLabelWidth" prop="reviewStatus">
|
||||
<el-select size="small" v-model="form.reviewStatus" class="ms-case-input">
|
||||
<el-option v-for="item in options" :key="item.id" :label="item.label" :value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-form-item :label="$t('commons.tag')" :label-width="formLabelWidth" prop="tag">
|
||||
<ms-input-tag :currentScenario="form" v-if="showInputTag" ref="tag" class="ms-case-input"/>
|
||||
|
@ -76,7 +85,8 @@
|
|||
</el-form-item>
|
||||
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="7">
|
||||
<el-form-item :label="$t('test_track.case.priority')" :label-width="formLabelWidth" prop="priority">
|
||||
<el-select :disabled="readOnly" v-model="form.priority" clearable
|
||||
|
@ -88,8 +98,6 @@
|
|||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="7">
|
||||
<el-form-item :label="$t('test_track.case.type')" :label-width="formLabelWidth" prop="type">
|
||||
<el-select @change="typeChange" :disabled="readOnly" v-model="form.type"
|
||||
|
@ -305,7 +313,7 @@
|
|||
|
||||
import {TokenKey, WORKSPACE_ID} from '@/common/js/constants';
|
||||
import MsDialogFooter from '../../../common/components/MsDialogFooter'
|
||||
import {listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||
import {getCurrentUser, listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
|
||||
import {Message} from "element-ui";
|
||||
import TestCaseAttachment from "@/business/components/track/case/components/TestCaseAttachment";
|
||||
|
@ -328,6 +336,7 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
options: REVIEW_STATUS,
|
||||
statuOptions:API_STATUS,
|
||||
comments: [],
|
||||
result: {},
|
||||
projectId: "",
|
||||
|
@ -335,8 +344,8 @@ export default {
|
|||
form: {
|
||||
name: '',
|
||||
module: '',
|
||||
maintainer: '',
|
||||
priority: '',
|
||||
maintainer: getCurrentUser().id,
|
||||
priority: 'P0',
|
||||
type: '',
|
||||
method: '',
|
||||
prerequisite: '',
|
||||
|
@ -351,6 +360,8 @@ export default {
|
|||
tags: [],
|
||||
demandId: '',
|
||||
demandName: '',
|
||||
status:'Prepare',
|
||||
reviewStatus:'Prepare',
|
||||
},
|
||||
readOnly: false,
|
||||
moduleOptions: [],
|
||||
|
@ -369,8 +380,6 @@ export default {
|
|||
module: [{required: true, message: this.$t('test_track.case.input_module'), trigger: 'change'}],
|
||||
maintainer: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
|
||||
priority: [{required: true, message: this.$t('test_track.case.input_priority'), trigger: 'change'}],
|
||||
type: [{required: true, message: this.$t('test_track.case.input_type'), trigger: 'change'}],
|
||||
testId: [{required: true, message: this.$t('commons.please_select'), trigger: 'change'}],
|
||||
method: [{required: true, message: this.$t('test_track.case.input_method'), trigger: 'change'}],
|
||||
prerequisite: [{max: 500, message: this.$t('test_track.length_less_than') + '500', trigger: 'blur'}],
|
||||
remark: [{max: 1000, message: this.$t('test_track.length_less_than') + '1000', trigger: 'blur'}]
|
||||
|
@ -543,7 +552,9 @@ export default {
|
|||
let tmp = {};
|
||||
Object.assign(tmp, testCase);
|
||||
tmp.steps = JSON.parse(testCase.steps);
|
||||
console.log(tmp)
|
||||
Object.assign(this.form, tmp);
|
||||
console.log(this.form)
|
||||
this.form.module = testCase.nodeId;
|
||||
this.getFileMetaData(testCase);
|
||||
},
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
<template>
|
||||
<ms-module-minder
|
||||
:tree-nodes="treeNodes"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsModuleMinder from "@/business/components/common/components/MsModuleMinder";
|
||||
export default {
|
||||
name: "TestCaseMinder",
|
||||
components: {MsModuleMinder},
|
||||
data() {
|
||||
return{
|
||||
testCase: [],
|
||||
dataMap: new Map()
|
||||
}
|
||||
},
|
||||
props: {
|
||||
treeNodes: {
|
||||
type: Array,
|
||||
default() {
|
||||
return []
|
||||
}
|
||||
},
|
||||
condition: Object,
|
||||
projectId: String
|
||||
},
|
||||
mounted() {
|
||||
// this.getTestCases();
|
||||
},
|
||||
methods: {
|
||||
getTestCases() {
|
||||
if (this.projectId) {
|
||||
this.result = this.$get('/test/case/list/detail/' + this.projectId,response => {
|
||||
this.testCase = response.data;
|
||||
console.log(this.testCase)
|
||||
this.parse();
|
||||
});
|
||||
}
|
||||
},
|
||||
parse() {
|
||||
this.testCase.forEach(item => {
|
||||
let mapItem = this.dataMap.get(item.moduleId);
|
||||
let nodeItem = {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
|
||||
}
|
||||
if (mapItem) {
|
||||
mapItem.push(item);
|
||||
} else {
|
||||
mapItem = [];
|
||||
mapItem.push(item);
|
||||
}
|
||||
if (item.tags && item.tags.length > 0) {
|
||||
item.tags = JSON.parse(item.tags);
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -1,25 +0,0 @@
|
|||
<template>
|
||||
<ms-module-minder
|
||||
:tree-nodes="treeNodes"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsModuleMinder from "@/business/components/common/components/MsModuleMinder";
|
||||
export default {
|
||||
name: "TestcaseMinder",
|
||||
components: {MsModuleMinder},
|
||||
props: {
|
||||
treeNodes: {
|
||||
type: Array,
|
||||
default() {
|
||||
return []
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -33,6 +33,7 @@
|
|||
</ms-node-tree>
|
||||
<test-case-import @refreshAll="refreshAll" ref="testCaseImport"></test-case-import>
|
||||
<test-case-create
|
||||
:tree-nodes="treeNodes"
|
||||
@saveAsEdit="saveAsEdit"
|
||||
@refresh="refresh"
|
||||
ref="testCaseCreate"
|
||||
|
@ -76,7 +77,10 @@ export default {
|
|||
watch: {
|
||||
treeNodes() {
|
||||
this.$emit('setTreeNodes', this.treeNodes);
|
||||
}
|
||||
},
|
||||
'condition.filterText'(val) {
|
||||
this.$refs.nodeTree.filter(val);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.projectId = getCurrentProjectID();
|
||||
|
@ -165,6 +169,12 @@ export default {
|
|||
},
|
||||
nodeChange(node, nodeIds, pNodes) {
|
||||
this.$emit("nodeSelectEvent", node, nodeIds, pNodes);
|
||||
this.currentModule = node.data;
|
||||
if (node.data.id === 'root') {
|
||||
this.$emit("nodeSelectEvent", node, [], pNodes);
|
||||
} else {
|
||||
this.$emit("nodeSelectEvent", node, nodeIds, pNodes);
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</template>
|
||||
<template v-slot:menu>
|
||||
<el-menu v-if="isMenuShow" active-text-color="#6d317c"
|
||||
class="el-menu-demo header-menu" mode="horizontal" @select="handleSelect">
|
||||
class="el-menu-demo header-menu" mode="horizontal" @select="handleSelect" :default-active="activeIndex">
|
||||
<el-menu-item index="functional">功能测试用例</el-menu-item>
|
||||
<el-menu-item index="api">接口测试用例</el-menu-item>
|
||||
<el-menu-item index="load">性能测试用例</el-menu-item>
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 17404980aab725889843ce8c65f5f5c00113ae21
|
||||
Subproject commit 4c33b9c3b12a83da6d9bd2740262c6c8baaab819
|
|
@ -1,366 +1,378 @@
|
|||
import {
|
||||
COUNT_NUMBER, COUNT_NUMBER_SHALLOW,
|
||||
LicenseKey, ORIGIN_COLOR, ORIGIN_COLOR_SHALLOW,
|
||||
PROJECT_ID,
|
||||
REFRESH_SESSION_USER_URL,
|
||||
ROLE_ADMIN,
|
||||
ROLE_ORG_ADMIN,
|
||||
ROLE_TEST_MANAGER,
|
||||
ROLE_TEST_USER,
|
||||
ROLE_TEST_VIEWER,
|
||||
TokenKey
|
||||
COUNT_NUMBER,
|
||||
COUNT_NUMBER_SHALLOW,
|
||||
LicenseKey,
|
||||
ORIGIN_COLOR,
|
||||
ORIGIN_COLOR_SHALLOW,
|
||||
PROJECT_ID,
|
||||
REFRESH_SESSION_USER_URL,
|
||||
ROLE_ADMIN,
|
||||
ROLE_ORG_ADMIN,
|
||||
ROLE_TEST_MANAGER,
|
||||
ROLE_TEST_USER,
|
||||
ROLE_TEST_VIEWER,
|
||||
TokenKey
|
||||
} from "./constants";
|
||||
import axios from "axios";
|
||||
import {jsPDF} from "jspdf";
|
||||
import JSEncrypt from 'jsencrypt';
|
||||
|
||||
export function hasRole(role) {
|
||||
let user = getCurrentUser();
|
||||
let roles = user.roles.map(r => r.id);
|
||||
return roles.indexOf(role) > -1;
|
||||
let user = getCurrentUser();
|
||||
let roles = user.roles.map(r => r.id);
|
||||
return roles.indexOf(role) > -1;
|
||||
}
|
||||
|
||||
// 是否含有某个角色
|
||||
export function hasRoles(...roles) {
|
||||
let user = getCurrentUser();
|
||||
let rs = user.roles.map(r => r.id);
|
||||
for (let item of roles) {
|
||||
if (rs.indexOf(item) > -1) {
|
||||
return true;
|
||||
let user = getCurrentUser();
|
||||
let rs = user.roles.map(r => r.id);
|
||||
for (let item of roles) {
|
||||
if (rs.indexOf(item) > -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
export function hasRolePermission(role) {
|
||||
let user = getCurrentUser();
|
||||
for (let ur of user.userRoles) {
|
||||
if (role === ur.roleId) {
|
||||
if (ur.roleId === ROLE_ADMIN) {
|
||||
return true;
|
||||
} else if (ur.roleId === ROLE_ORG_ADMIN && user.lastOrganizationId === ur.sourceId) {
|
||||
return true;
|
||||
} else if (user.lastWorkspaceId === ur.sourceId) {
|
||||
return true;
|
||||
}
|
||||
let user = getCurrentUser();
|
||||
for (let ur of user.userRoles) {
|
||||
if (role === ur.roleId) {
|
||||
if (ur.roleId === ROLE_ADMIN) {
|
||||
return true;
|
||||
} else if (ur.roleId === ROLE_ORG_ADMIN && user.lastOrganizationId === ur.sourceId) {
|
||||
return true;
|
||||
} else if (user.lastWorkspaceId === ur.sourceId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
return false
|
||||
}
|
||||
|
||||
export function hasLicense() {
|
||||
let v = localStorage.getItem(LicenseKey);
|
||||
return v === 'valid';
|
||||
let v = localStorage.getItem(LicenseKey);
|
||||
return v === 'valid';
|
||||
}
|
||||
|
||||
//是否含有对应组织或工作空间的角色
|
||||
export function hasRolePermissions(...roles) {
|
||||
for (let role of roles) {
|
||||
if (hasRolePermission(role)) {
|
||||
return true;
|
||||
for (let role of roles) {
|
||||
if (hasRolePermission(role)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
export function checkoutCurrentOrganization() {
|
||||
// 查看当前用户是否是 lastOrganizationId 的组织管理员
|
||||
return hasRolePermissions(ROLE_ORG_ADMIN);
|
||||
// 查看当前用户是否是 lastOrganizationId 的组织管理员
|
||||
return hasRolePermissions(ROLE_ORG_ADMIN);
|
||||
}
|
||||
|
||||
export function checkoutCurrentWorkspace() {
|
||||
// 查看当前用户是否是 lastWorkspaceId 的工作空间用户
|
||||
return hasRolePermissions(ROLE_TEST_MANAGER, ROLE_TEST_USER, ROLE_TEST_VIEWER);
|
||||
// 查看当前用户是否是 lastWorkspaceId 的工作空间用户
|
||||
return hasRolePermissions(ROLE_TEST_MANAGER, ROLE_TEST_USER, ROLE_TEST_VIEWER);
|
||||
}
|
||||
|
||||
export function checkoutTestManagerOrTestUser() {
|
||||
return hasRolePermissions(ROLE_TEST_MANAGER, ROLE_TEST_USER);
|
||||
return hasRolePermissions(ROLE_TEST_MANAGER, ROLE_TEST_USER);
|
||||
}
|
||||
|
||||
export function getCurrentOrganizationId() {
|
||||
let user = getCurrentUser();
|
||||
return user.lastOrganizationId;
|
||||
let user = getCurrentUser();
|
||||
return user.lastOrganizationId;
|
||||
}
|
||||
|
||||
export function getCurrentWorkspaceId() {
|
||||
let user = getCurrentUser();
|
||||
return user.lastWorkspaceId;
|
||||
let user = getCurrentUser();
|
||||
return user.lastWorkspaceId;
|
||||
}
|
||||
|
||||
export function getCurrentUser() {
|
||||
return JSON.parse(localStorage.getItem(TokenKey));
|
||||
return JSON.parse(localStorage.getItem(TokenKey));
|
||||
}
|
||||
|
||||
export function getCurrentProjectID() {
|
||||
return localStorage.getItem(PROJECT_ID);
|
||||
return localStorage.getItem(PROJECT_ID);
|
||||
}
|
||||
|
||||
export function saveLocalStorage(response) {
|
||||
// 登录信息保存 cookie
|
||||
localStorage.setItem(TokenKey, JSON.stringify(response.data));
|
||||
let rolesArray = response.data.roles;
|
||||
let roles = rolesArray.map(r => r.id);
|
||||
// 保存角色
|
||||
localStorage.setItem("roles", roles);
|
||||
// 登录信息保存 cookie
|
||||
localStorage.setItem(TokenKey, JSON.stringify(response.data));
|
||||
let rolesArray = response.data.roles;
|
||||
let roles = rolesArray.map(r => r.id);
|
||||
// 保存角色
|
||||
localStorage.setItem("roles", roles);
|
||||
}
|
||||
|
||||
export function saveLicense(data) {
|
||||
// 保存License
|
||||
localStorage.setItem(LicenseKey, data);
|
||||
// 保存License
|
||||
localStorage.setItem(LicenseKey, data);
|
||||
}
|
||||
|
||||
|
||||
export function refreshSessionAndCookies(sign, sourceId) {
|
||||
axios.post(REFRESH_SESSION_USER_URL + "/" + sign + "/" + sourceId).then(r => {
|
||||
saveLocalStorage(r.data);
|
||||
window.location.reload();
|
||||
})
|
||||
axios.post(REFRESH_SESSION_USER_URL + "/" + sign + "/" + sourceId).then(r => {
|
||||
saveLocalStorage(r.data);
|
||||
window.location.reload();
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export function jsonToMap(jsonStr) {
|
||||
let obj = JSON.parse(jsonStr);
|
||||
let strMap = new Map();
|
||||
for (let k of Object.keys(obj)) {
|
||||
strMap.set(k, obj[k]);
|
||||
}
|
||||
return strMap;
|
||||
let obj = JSON.parse(jsonStr);
|
||||
let strMap = new Map();
|
||||
for (let k of Object.keys(obj)) {
|
||||
strMap.set(k, obj[k]);
|
||||
}
|
||||
return strMap;
|
||||
}
|
||||
|
||||
export function mapToJson(strMap) {
|
||||
let obj = Object.create(null);
|
||||
for (let [k, v] of strMap) {
|
||||
obj[k] = v;
|
||||
}
|
||||
return JSON.stringify(obj);
|
||||
let obj = Object.create(null);
|
||||
for (let [k, v] of strMap) {
|
||||
obj[k] = v;
|
||||
}
|
||||
return JSON.stringify(obj);
|
||||
}
|
||||
|
||||
// 驼峰转换下划线
|
||||
export function humpToLine(name) {
|
||||
return name.replace(/([A-Z])/g, "_$1").toLowerCase();
|
||||
return name.replace(/([A-Z])/g, "_$1").toLowerCase();
|
||||
}
|
||||
|
||||
export function downloadFile(name, content) {
|
||||
const blob = new Blob([content]);
|
||||
if ("download" in document.createElement("a")) {
|
||||
// 非IE下载
|
||||
// chrome/firefox
|
||||
let aTag = document.createElement('a');
|
||||
aTag.download = name;
|
||||
aTag.href = URL.createObjectURL(blob);
|
||||
aTag.click();
|
||||
URL.revokeObjectURL(aTag.href)
|
||||
} else {
|
||||
// IE10+下载
|
||||
navigator.msSaveBlob(blob, name)
|
||||
}
|
||||
const blob = new Blob([content]);
|
||||
if ("download" in document.createElement("a")) {
|
||||
// 非IE下载
|
||||
// chrome/firefox
|
||||
let aTag = document.createElement('a');
|
||||
aTag.download = name;
|
||||
aTag.href = URL.createObjectURL(blob);
|
||||
aTag.click();
|
||||
URL.revokeObjectURL(aTag.href)
|
||||
} else {
|
||||
// IE10+下载
|
||||
navigator.msSaveBlob(blob, name)
|
||||
}
|
||||
}
|
||||
|
||||
export function listenGoBack(callback) {
|
||||
//监听浏览器返回操作,关闭该对话框
|
||||
if (window.history && window.history.pushState) {
|
||||
history.pushState(null, null, document.URL);
|
||||
window.addEventListener('popstate', callback);
|
||||
}
|
||||
//监听浏览器返回操作,关闭该对话框
|
||||
if (window.history && window.history.pushState) {
|
||||
history.pushState(null, null, document.URL);
|
||||
window.addEventListener('popstate', callback);
|
||||
}
|
||||
}
|
||||
|
||||
export function removeGoBackListener(callback) {
|
||||
window.removeEventListener('popstate', callback);
|
||||
window.removeEventListener('popstate', callback);
|
||||
}
|
||||
|
||||
export const uuid = function () {
|
||||
let d = new Date().getTime();
|
||||
let d2 = (performance && performance.now && (performance.now() * 1000)) || 0;
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
let r = Math.random() * 16;
|
||||
if (d > 0) {
|
||||
r = (d + r) % 16 | 0;
|
||||
d = Math.floor(d / 16);
|
||||
} else {
|
||||
r = (d2 + r) % 16 | 0;
|
||||
d2 = Math.floor(d2 / 16);
|
||||
}
|
||||
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
|
||||
});
|
||||
let d = new Date().getTime();
|
||||
let d2 = (performance && performance.now && (performance.now() * 1000)) || 0;
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
let r = Math.random() * 16;
|
||||
if (d > 0) {
|
||||
r = (d + r) % 16 | 0;
|
||||
d = Math.floor(d / 16);
|
||||
} else {
|
||||
r = (d2 + r) % 16 | 0;
|
||||
d2 = Math.floor(d2 / 16);
|
||||
}
|
||||
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
|
||||
});
|
||||
};
|
||||
|
||||
export function getUUID() {
|
||||
function S4() {
|
||||
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
|
||||
}
|
||||
function S4() {
|
||||
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
|
||||
}
|
||||
|
||||
return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
|
||||
return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
|
||||
}
|
||||
|
||||
|
||||
export function exportPdf(name, canvasList) {
|
||||
|
||||
let pdf = new jsPDF('', 'pt', 'a4');
|
||||
let pdf = new jsPDF('', 'pt', 'a4');
|
||||
|
||||
// 当前页面的当前高度
|
||||
let currentHeight = 0;
|
||||
for (let canvas of canvasList) {
|
||||
if (canvas) {
|
||||
// 当前页面的当前高度
|
||||
let currentHeight = 0;
|
||||
for (let canvas of canvasList) {
|
||||
if (canvas) {
|
||||
|
||||
let contentWidth = canvas.width;
|
||||
let contentHeight = canvas.height;
|
||||
let contentWidth = canvas.width;
|
||||
let contentHeight = canvas.height;
|
||||
|
||||
//a4纸的尺寸[595.28,841.89]
|
||||
let a4Width = 592.28;
|
||||
let a4Height = 841.89;
|
||||
//a4纸的尺寸[595.28,841.89]
|
||||
let a4Width = 592.28;
|
||||
let a4Height = 841.89;
|
||||
|
||||
// html页面生成的canvas在pdf中图片的宽高
|
||||
let imgWidth = a4Width;
|
||||
let imgHeight = a4Width / contentWidth * contentHeight;
|
||||
// html页面生成的canvas在pdf中图片的宽高
|
||||
let imgWidth = a4Width;
|
||||
let imgHeight = a4Width / contentWidth * contentHeight;
|
||||
|
||||
let pageData = canvas.toDataURL('image/jpeg', 1.0);
|
||||
let pageData = canvas.toDataURL('image/jpeg', 1.0);
|
||||
|
||||
// 当前图片的剩余高度
|
||||
let leftHeight = imgHeight;
|
||||
// 当前图片的剩余高度
|
||||
let leftHeight = imgHeight;
|
||||
|
||||
// 当前页面的剩余高度
|
||||
let blankHeight = a4Height - currentHeight;
|
||||
// 当前页面的剩余高度
|
||||
let blankHeight = a4Height - currentHeight;
|
||||
|
||||
if (leftHeight > blankHeight) {
|
||||
//页面偏移
|
||||
let position = 0;
|
||||
while (leftHeight > 0) {
|
||||
// 本次添加占用的高度
|
||||
let occupation = a4Height - currentHeight;
|
||||
pdf.addImage(pageData, 'JPEG', 0, position + currentHeight, imgWidth, imgHeight);
|
||||
currentHeight = leftHeight;
|
||||
leftHeight -= occupation;
|
||||
position -= occupation;
|
||||
//避免添加空白页
|
||||
if (leftHeight > 0) {
|
||||
pdf.addPage();
|
||||
currentHeight = 0;
|
||||
}
|
||||
if (leftHeight > blankHeight) {
|
||||
//页面偏移
|
||||
let position = 0;
|
||||
while (leftHeight > 0) {
|
||||
// 本次添加占用的高度
|
||||
let occupation = a4Height - currentHeight;
|
||||
pdf.addImage(pageData, 'JPEG', 0, position + currentHeight, imgWidth, imgHeight);
|
||||
currentHeight = leftHeight;
|
||||
leftHeight -= occupation;
|
||||
position -= occupation;
|
||||
//避免添加空白页
|
||||
if (leftHeight > 0) {
|
||||
pdf.addPage();
|
||||
currentHeight = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pdf.addImage(pageData, 'JPEG', 0, currentHeight, imgWidth, imgHeight);
|
||||
currentHeight += imgHeight;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pdf.addImage(pageData, 'JPEG', 0, currentHeight, imgWidth, imgHeight);
|
||||
currentHeight += imgHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pdf.save(name.replace(" ", "_") + '.pdf');
|
||||
pdf.save(name.replace(" ", "_") + '.pdf');
|
||||
|
||||
}
|
||||
|
||||
export function windowPrint(id, zoom) {
|
||||
//根据div标签ID拿到div中的局部内容
|
||||
let bdhtml = window.document.body.innerHTML;
|
||||
let el = document.getElementById(id);
|
||||
var jubuData = el.innerHTML;
|
||||
document.getElementsByTagName('body')[0].style.zoom = zoom;
|
||||
//把获取的 局部div内容赋给body标签, 相当于重置了 body里的内容
|
||||
window.document.body.innerHTML = jubuData;
|
||||
//调用打印功能
|
||||
window.print();
|
||||
window.document.body.innerHTML = bdhtml;//重新给页面内容赋值;
|
||||
return false;
|
||||
//根据div标签ID拿到div中的局部内容
|
||||
let bdhtml = window.document.body.innerHTML;
|
||||
let el = document.getElementById(id);
|
||||
var jubuData = el.innerHTML;
|
||||
document.getElementsByTagName('body')[0].style.zoom = zoom;
|
||||
//把获取的 局部div内容赋给body标签, 相当于重置了 body里的内容
|
||||
window.document.body.innerHTML = jubuData;
|
||||
//调用打印功能
|
||||
window.print();
|
||||
window.document.body.innerHTML = bdhtml;//重新给页面内容赋值;
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getBodyUploadFiles(obj, runData) {
|
||||
let bodyUploadFiles = [];
|
||||
obj.bodyUploadIds = [];
|
||||
if (runData) {
|
||||
if (runData instanceof Array) {
|
||||
runData.forEach(request => {
|
||||
_getBodyUploadFiles(request, bodyUploadFiles, obj);
|
||||
});
|
||||
} else {
|
||||
_getBodyUploadFiles(runData, bodyUploadFiles, obj);
|
||||
let bodyUploadFiles = [];
|
||||
obj.bodyUploadIds = [];
|
||||
if (runData) {
|
||||
if (runData instanceof Array) {
|
||||
runData.forEach(request => {
|
||||
_getBodyUploadFiles(request, bodyUploadFiles, obj);
|
||||
});
|
||||
} else {
|
||||
_getBodyUploadFiles(runData, bodyUploadFiles, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bodyUploadFiles;
|
||||
return bodyUploadFiles;
|
||||
}
|
||||
|
||||
export function _getBodyUploadFiles(request, bodyUploadFiles, obj) {
|
||||
let body = null;
|
||||
if (request.hashTree && request.hashTree.length > 0 && request.hashTree[0].body) {
|
||||
body = request.hashTree[0].body;
|
||||
} else if (request.body) {
|
||||
body = request.body;
|
||||
}
|
||||
if (body) {
|
||||
if (body.kvs) {
|
||||
body.kvs.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
if (!item.id) {
|
||||
let fileId = getUUID().substring(0, 12);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
}
|
||||
obj.bodyUploadIds.push(item.id);
|
||||
bodyUploadFiles.push(item.file);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
let body = null;
|
||||
if (request.hashTree && request.hashTree.length > 0 && request.hashTree[0].body) {
|
||||
body = request.hashTree[0].body;
|
||||
} else if (request.body) {
|
||||
body = request.body;
|
||||
}
|
||||
if (body.binary) {
|
||||
body.binary.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
if (!item.id) {
|
||||
let fileId = getUUID().substring(0, 12);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
}
|
||||
obj.bodyUploadIds.push(item.id);
|
||||
bodyUploadFiles.push(item.file);
|
||||
}
|
||||
});
|
||||
if (body) {
|
||||
if (body.kvs) {
|
||||
body.kvs.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
if (!item.id) {
|
||||
let fileId = getUUID().substring(0, 12);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
}
|
||||
obj.bodyUploadIds.push(item.id);
|
||||
bodyUploadFiles.push(item.file);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if (body.binary) {
|
||||
body.binary.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
if (!item.id) {
|
||||
let fileId = getUUID().substring(0, 12);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
}
|
||||
obj.bodyUploadIds.push(item.id);
|
||||
bodyUploadFiles.push(item.file);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function handleCtrlSEvent(event, func) {
|
||||
if (event.keyCode === 83 && event.ctrlKey) {
|
||||
// console.log('拦截到 ctrl + s');//ctrl+s
|
||||
func();
|
||||
event.preventDefault();
|
||||
event.returnValue = false;
|
||||
return false;
|
||||
}
|
||||
if (event.keyCode === 83 && event.ctrlKey) {
|
||||
// console.log('拦截到 ctrl + s');//ctrl+s
|
||||
func();
|
||||
event.preventDefault();
|
||||
event.returnValue = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function strMapToObj(strMap) {
|
||||
if (strMap) {
|
||||
let obj = Object.create(null);
|
||||
for (let [k, v] of strMap) {
|
||||
obj[k] = v;
|
||||
if (strMap) {
|
||||
let obj = Object.create(null);
|
||||
for (let [k, v] of strMap) {
|
||||
obj[k] = v;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
export function objToStrMap(obj) {
|
||||
let strMap = new Map();
|
||||
for (let k of Object.keys(obj)) {
|
||||
strMap.set(k, obj[k]);
|
||||
}
|
||||
return strMap;
|
||||
let strMap = new Map();
|
||||
for (let k of Object.keys(obj)) {
|
||||
strMap.set(k, obj[k]);
|
||||
}
|
||||
return strMap;
|
||||
}
|
||||
|
||||
export function getColor() {
|
||||
return localStorage.getItem('color');
|
||||
return localStorage.getItem('color');
|
||||
}
|
||||
|
||||
export function setColor(a, b, c, d) {
|
||||
document.body.style.setProperty('--color', a);
|
||||
document.body.style.setProperty('--color_shallow', b);
|
||||
document.body.style.setProperty('--count_number', c);
|
||||
document.body.style.setProperty('--count_number_shallow', d);
|
||||
document.body.style.setProperty('--color', a);
|
||||
document.body.style.setProperty('--color_shallow', b);
|
||||
document.body.style.setProperty('--count_number', c);
|
||||
document.body.style.setProperty('--count_number_shallow', d);
|
||||
}
|
||||
|
||||
export function setOriginColor() {
|
||||
setColor(ORIGIN_COLOR, ORIGIN_COLOR_SHALLOW, COUNT_NUMBER, COUNT_NUMBER_SHALLOW);
|
||||
setColor(ORIGIN_COLOR, ORIGIN_COLOR_SHALLOW, COUNT_NUMBER, COUNT_NUMBER_SHALLOW);
|
||||
}
|
||||
|
||||
export function publicKeyEncrypt(input, publicKey) {
|
||||
|
||||
let jsencrypt = new JSEncrypt({default_key_size: 1024});
|
||||
jsencrypt.setPublicKey(publicKey);
|
||||
|
||||
return jsencrypt.encrypt(input);
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import {saveLocalStorage} from '@/common/js/utils';
|
||||
import {publicKeyEncrypt, saveLocalStorage} from '@/common/js/utils';
|
||||
import {DEFAULT_LANGUAGE} from "@/common/js/constants";
|
||||
|
||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||
|
@ -103,6 +103,8 @@ export default {
|
|||
|
||||
if (!response.data.success) {
|
||||
this.ready = true;
|
||||
// 保存公钥
|
||||
localStorage.setItem("publicKey", response.data.message);
|
||||
} else {
|
||||
let user = response.data.data;
|
||||
saveLocalStorage(response.data);
|
||||
|
@ -159,7 +161,15 @@ export default {
|
|||
});
|
||||
},
|
||||
doLogin() {
|
||||
this.result = this.$post(this.loginUrl, this.form, response => {
|
||||
let publicKey = localStorage.getItem("publicKey");
|
||||
|
||||
let form = {
|
||||
username: publicKeyEncrypt(this.form.username, publicKey),
|
||||
password: publicKeyEncrypt(this.form.password, publicKey),
|
||||
authenticate: this.form.authenticate
|
||||
};
|
||||
|
||||
this.result = this.$post(this.loginUrl, form, response => {
|
||||
saveLocalStorage(response);
|
||||
sessionStorage.setItem('loginSuccess', 'true');
|
||||
this.getLanguage(response.data.language);
|
||||
|
|
Loading…
Reference in New Issue