Merge branch 'master' of https://github.com/metersphere/metersphere
Conflicts: backend/pom.xml
This commit is contained in:
commit
8bcf1ebc4c
|
@ -60,6 +60,7 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-mail</artifactId>
|
<artifactId>spring-boot-starter-mail</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
|
@ -75,6 +76,7 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- flyway -->
|
<!-- flyway -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.flywaydb</groupId>
|
<groupId>org.flywaydb</groupId>
|
||||||
|
@ -153,6 +155,12 @@
|
||||||
<version>2.1.7</version>
|
<version>2.1.7</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.quartz-scheduler</groupId>
|
||||||
|
<artifactId>quartz</artifactId>
|
||||||
|
<version>2.3.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- LDAP Module -->
|
<!-- LDAP Module -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
|
|
@ -50,6 +50,11 @@ public class APITestController {
|
||||||
return apiTestService.getApiTestByProjectId(projectId);
|
return apiTestService.getApiTestByProjectId(projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = "/schedule/update")
|
||||||
|
public void updateSchedule(@RequestBody SaveAPITestRequest request) {
|
||||||
|
apiTestService.updateSchedule(request);
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/create", consumes = {"multipart/form-data"})
|
@PostMapping(value = "/create", consumes = {"multipart/form-data"})
|
||||||
public void create(@RequestPart("request") SaveAPITestRequest request, @RequestPart(value = "files") List<MultipartFile> files) {
|
public void create(@RequestPart("request") SaveAPITestRequest request, @RequestPart(value = "files") List<MultipartFile> files) {
|
||||||
apiTestService.create(request, files);
|
apiTestService.create(request, files);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package io.metersphere.api.dto;
|
package io.metersphere.api.dto;
|
||||||
|
|
||||||
import io.metersphere.api.dto.scenario.Scenario;
|
import io.metersphere.api.dto.scenario.Scenario;
|
||||||
|
import io.metersphere.dto.ScheduleDTO;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@ -17,4 +18,6 @@ public class SaveAPITestRequest {
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
private List<Scenario> scenarioDefinition;
|
private List<Scenario> scenarioDefinition;
|
||||||
|
|
||||||
|
private ScheduleDTO schedule;
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,4 +207,14 @@ public class APITestService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateSchedule(SaveAPITestRequest request) {
|
||||||
|
|
||||||
|
// todo 开启调度线程
|
||||||
|
|
||||||
|
ApiTestWithBLOBs apiTest = new ApiTestWithBLOBs();
|
||||||
|
apiTest.setId(request.getId());
|
||||||
|
apiTest.setSchedule(JSONObject.toJSONString(request.getSchedule()));
|
||||||
|
apiTest.setUpdateTime(System.currentTimeMillis());
|
||||||
|
apiTestMapper.updateByPrimaryKeySelective(apiTest);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package io.metersphere.base.domain;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class UserKey implements Serializable {
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
private String accessKey;
|
||||||
|
|
||||||
|
private String secretKey;
|
||||||
|
|
||||||
|
private Long createTime;
|
||||||
|
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
|
@ -0,0 +1,610 @@
|
||||||
|
package io.metersphere.base.domain;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class UserKeyExample {
|
||||||
|
protected String orderByClause;
|
||||||
|
|
||||||
|
protected boolean distinct;
|
||||||
|
|
||||||
|
protected List<Criteria> oredCriteria;
|
||||||
|
|
||||||
|
public UserKeyExample() {
|
||||||
|
oredCriteria = new ArrayList<Criteria>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderByClause(String orderByClause) {
|
||||||
|
this.orderByClause = orderByClause;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderByClause() {
|
||||||
|
return orderByClause;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDistinct(boolean distinct) {
|
||||||
|
this.distinct = distinct;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDistinct() {
|
||||||
|
return distinct;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Criteria> getOredCriteria() {
|
||||||
|
return oredCriteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void or(Criteria criteria) {
|
||||||
|
oredCriteria.add(criteria);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria or() {
|
||||||
|
Criteria criteria = createCriteriaInternal();
|
||||||
|
oredCriteria.add(criteria);
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria createCriteria() {
|
||||||
|
Criteria criteria = createCriteriaInternal();
|
||||||
|
if (oredCriteria.size() == 0) {
|
||||||
|
oredCriteria.add(criteria);
|
||||||
|
}
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Criteria createCriteriaInternal() {
|
||||||
|
Criteria criteria = new Criteria();
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
oredCriteria.clear();
|
||||||
|
orderByClause = null;
|
||||||
|
distinct = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract static class GeneratedCriteria {
|
||||||
|
protected List<Criterion> criteria;
|
||||||
|
|
||||||
|
protected GeneratedCriteria() {
|
||||||
|
super();
|
||||||
|
criteria = new ArrayList<Criterion>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid() {
|
||||||
|
return criteria.size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Criterion> getAllCriteria() {
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Criterion> getCriteria() {
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addCriterion(String condition) {
|
||||||
|
if (condition == null) {
|
||||||
|
throw new RuntimeException("Value for condition cannot be null");
|
||||||
|
}
|
||||||
|
criteria.add(new Criterion(condition));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addCriterion(String condition, Object value, String property) {
|
||||||
|
if (value == null) {
|
||||||
|
throw new RuntimeException("Value for " + property + " cannot be null");
|
||||||
|
}
|
||||||
|
criteria.add(new Criterion(condition, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addCriterion(String condition, Object value1, Object value2, String property) {
|
||||||
|
if (value1 == null || value2 == null) {
|
||||||
|
throw new RuntimeException("Between values for " + property + " cannot be null");
|
||||||
|
}
|
||||||
|
criteria.add(new Criterion(condition, value1, value2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdIsNull() {
|
||||||
|
addCriterion("id is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdIsNotNull() {
|
||||||
|
addCriterion("id is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdEqualTo(String value) {
|
||||||
|
addCriterion("id =", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdNotEqualTo(String value) {
|
||||||
|
addCriterion("id <>", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdGreaterThan(String value) {
|
||||||
|
addCriterion("id >", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("id >=", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdLessThan(String value) {
|
||||||
|
addCriterion("id <", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("id <=", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdLike(String value) {
|
||||||
|
addCriterion("id like", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdNotLike(String value) {
|
||||||
|
addCriterion("id not like", value, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdIn(List<String> values) {
|
||||||
|
addCriterion("id in", values, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdNotIn(List<String> values) {
|
||||||
|
addCriterion("id not in", values, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdBetween(String value1, String value2) {
|
||||||
|
addCriterion("id between", value1, value2, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andIdNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("id not between", value1, value2, "id");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUserIdIsNull() {
|
||||||
|
addCriterion("user_id is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUserIdIsNotNull() {
|
||||||
|
addCriterion("user_id is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUserIdEqualTo(String value) {
|
||||||
|
addCriterion("user_id =", value, "userId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUserIdNotEqualTo(String value) {
|
||||||
|
addCriterion("user_id <>", value, "userId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUserIdGreaterThan(String value) {
|
||||||
|
addCriterion("user_id >", value, "userId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUserIdGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("user_id >=", value, "userId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUserIdLessThan(String value) {
|
||||||
|
addCriterion("user_id <", value, "userId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUserIdLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("user_id <=", value, "userId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUserIdLike(String value) {
|
||||||
|
addCriterion("user_id like", value, "userId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUserIdNotLike(String value) {
|
||||||
|
addCriterion("user_id not like", value, "userId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUserIdIn(List<String> values) {
|
||||||
|
addCriterion("user_id in", values, "userId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUserIdNotIn(List<String> values) {
|
||||||
|
addCriterion("user_id not in", values, "userId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUserIdBetween(String value1, String value2) {
|
||||||
|
addCriterion("user_id between", value1, value2, "userId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andUserIdNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("user_id not between", value1, value2, "userId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAccessKeyIsNull() {
|
||||||
|
addCriterion("access_key is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAccessKeyIsNotNull() {
|
||||||
|
addCriterion("access_key is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAccessKeyEqualTo(String value) {
|
||||||
|
addCriterion("access_key =", value, "accessKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAccessKeyNotEqualTo(String value) {
|
||||||
|
addCriterion("access_key <>", value, "accessKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAccessKeyGreaterThan(String value) {
|
||||||
|
addCriterion("access_key >", value, "accessKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAccessKeyGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("access_key >=", value, "accessKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAccessKeyLessThan(String value) {
|
||||||
|
addCriterion("access_key <", value, "accessKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAccessKeyLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("access_key <=", value, "accessKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAccessKeyLike(String value) {
|
||||||
|
addCriterion("access_key like", value, "accessKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAccessKeyNotLike(String value) {
|
||||||
|
addCriterion("access_key not like", value, "accessKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAccessKeyIn(List<String> values) {
|
||||||
|
addCriterion("access_key in", values, "accessKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAccessKeyNotIn(List<String> values) {
|
||||||
|
addCriterion("access_key not in", values, "accessKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAccessKeyBetween(String value1, String value2) {
|
||||||
|
addCriterion("access_key between", value1, value2, "accessKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andAccessKeyNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("access_key not between", value1, value2, "accessKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andSecretKeyIsNull() {
|
||||||
|
addCriterion("secret_key is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andSecretKeyIsNotNull() {
|
||||||
|
addCriterion("secret_key is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andSecretKeyEqualTo(String value) {
|
||||||
|
addCriterion("secret_key =", value, "secretKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andSecretKeyNotEqualTo(String value) {
|
||||||
|
addCriterion("secret_key <>", value, "secretKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andSecretKeyGreaterThan(String value) {
|
||||||
|
addCriterion("secret_key >", value, "secretKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andSecretKeyGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("secret_key >=", value, "secretKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andSecretKeyLessThan(String value) {
|
||||||
|
addCriterion("secret_key <", value, "secretKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andSecretKeyLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("secret_key <=", value, "secretKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andSecretKeyLike(String value) {
|
||||||
|
addCriterion("secret_key like", value, "secretKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andSecretKeyNotLike(String value) {
|
||||||
|
addCriterion("secret_key not like", value, "secretKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andSecretKeyIn(List<String> values) {
|
||||||
|
addCriterion("secret_key in", values, "secretKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andSecretKeyNotIn(List<String> values) {
|
||||||
|
addCriterion("secret_key not in", values, "secretKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andSecretKeyBetween(String value1, String value2) {
|
||||||
|
addCriterion("secret_key between", value1, value2, "secretKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andSecretKeyNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("secret_key not between", value1, value2, "secretKey");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeIsNull() {
|
||||||
|
addCriterion("create_time is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeIsNotNull() {
|
||||||
|
addCriterion("create_time is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeEqualTo(Long value) {
|
||||||
|
addCriterion("create_time =", value, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeNotEqualTo(Long value) {
|
||||||
|
addCriterion("create_time <>", value, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeGreaterThan(Long value) {
|
||||||
|
addCriterion("create_time >", value, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeGreaterThanOrEqualTo(Long value) {
|
||||||
|
addCriterion("create_time >=", value, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeLessThan(Long value) {
|
||||||
|
addCriterion("create_time <", value, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeLessThanOrEqualTo(Long value) {
|
||||||
|
addCriterion("create_time <=", value, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeIn(List<Long> values) {
|
||||||
|
addCriterion("create_time in", values, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeNotIn(List<Long> values) {
|
||||||
|
addCriterion("create_time not in", values, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeBetween(Long value1, Long value2) {
|
||||||
|
addCriterion("create_time between", value1, value2, "createTime");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andCreateTimeNotBetween(Long value1, Long value2) {
|
||||||
|
addCriterion("create_time not between", value1, value2, "createTime");
|
||||||
|
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 {
|
||||||
|
|
||||||
|
protected Criteria() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Criterion {
|
||||||
|
private String condition;
|
||||||
|
|
||||||
|
private Object value;
|
||||||
|
|
||||||
|
private Object secondValue;
|
||||||
|
|
||||||
|
private boolean noValue;
|
||||||
|
|
||||||
|
private boolean singleValue;
|
||||||
|
|
||||||
|
private boolean betweenValue;
|
||||||
|
|
||||||
|
private boolean listValue;
|
||||||
|
|
||||||
|
private String typeHandler;
|
||||||
|
|
||||||
|
public String getCondition() {
|
||||||
|
return condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getSecondValue() {
|
||||||
|
return secondValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNoValue() {
|
||||||
|
return noValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSingleValue() {
|
||||||
|
return singleValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBetweenValue() {
|
||||||
|
return betweenValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isListValue() {
|
||||||
|
return listValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTypeHandler() {
|
||||||
|
return typeHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Criterion(String condition) {
|
||||||
|
super();
|
||||||
|
this.condition = condition;
|
||||||
|
this.typeHandler = null;
|
||||||
|
this.noValue = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Criterion(String condition, Object value, String typeHandler) {
|
||||||
|
super();
|
||||||
|
this.condition = condition;
|
||||||
|
this.value = value;
|
||||||
|
this.typeHandler = typeHandler;
|
||||||
|
if (value instanceof List<?>) {
|
||||||
|
this.listValue = true;
|
||||||
|
} else {
|
||||||
|
this.singleValue = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Criterion(String condition, Object value) {
|
||||||
|
this(condition, value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
|
||||||
|
super();
|
||||||
|
this.condition = condition;
|
||||||
|
this.value = value;
|
||||||
|
this.secondValue = secondValue;
|
||||||
|
this.typeHandler = typeHandler;
|
||||||
|
this.betweenValue = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Criterion(String condition, Object value, Object secondValue) {
|
||||||
|
this(condition, value, secondValue, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package io.metersphere.base.mapper;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.UserKey;
|
||||||
|
import io.metersphere.base.domain.UserKeyExample;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface UserKeyMapper {
|
||||||
|
long countByExample(UserKeyExample example);
|
||||||
|
|
||||||
|
int deleteByExample(UserKeyExample example);
|
||||||
|
|
||||||
|
int deleteByPrimaryKey(String id);
|
||||||
|
|
||||||
|
int insert(UserKey record);
|
||||||
|
|
||||||
|
int insertSelective(UserKey record);
|
||||||
|
|
||||||
|
List<UserKey> selectByExample(UserKeyExample example);
|
||||||
|
|
||||||
|
UserKey selectByPrimaryKey(String id);
|
||||||
|
|
||||||
|
int updateByExampleSelective(@Param("record") UserKey record, @Param("example") UserKeyExample example);
|
||||||
|
|
||||||
|
int updateByExample(@Param("record") UserKey record, @Param("example") UserKeyExample example);
|
||||||
|
|
||||||
|
int updateByPrimaryKeySelective(UserKey record);
|
||||||
|
|
||||||
|
int updateByPrimaryKey(UserKey record);
|
||||||
|
}
|
|
@ -0,0 +1,228 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="io.metersphere.base.mapper.UserKeyMapper">
|
||||||
|
<resultMap id="BaseResultMap" type="io.metersphere.base.domain.UserKey">
|
||||||
|
<id column="id" jdbcType="VARCHAR" property="id" />
|
||||||
|
<result column="user_id" jdbcType="VARCHAR" property="userId" />
|
||||||
|
<result column="access_key" jdbcType="VARCHAR" property="accessKey" />
|
||||||
|
<result column="secret_key" jdbcType="VARCHAR" property="secretKey" />
|
||||||
|
<result column="create_time" jdbcType="BIGINT" property="createTime" />
|
||||||
|
<result column="status" jdbcType="VARCHAR" property="status" />
|
||||||
|
</resultMap>
|
||||||
|
<sql id="Example_Where_Clause">
|
||||||
|
<where>
|
||||||
|
<foreach collection="oredCriteria" item="criteria" separator="or">
|
||||||
|
<if test="criteria.valid">
|
||||||
|
<trim prefix="(" prefixOverrides="and" suffix=")">
|
||||||
|
<foreach collection="criteria.criteria" item="criterion">
|
||||||
|
<choose>
|
||||||
|
<when test="criterion.noValue">
|
||||||
|
and ${criterion.condition}
|
||||||
|
</when>
|
||||||
|
<when test="criterion.singleValue">
|
||||||
|
AND ${criterion.condition} #{criterion.value}
|
||||||
|
</when>
|
||||||
|
<when test="criterion.betweenValue">
|
||||||
|
AND ${criterion.condition} #{criterion.value} AND #{criterion.secondValue}
|
||||||
|
</when>
|
||||||
|
<when test="criterion.listValue">
|
||||||
|
AND ${criterion.condition}
|
||||||
|
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
|
||||||
|
#{listItem}
|
||||||
|
</foreach>
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
</foreach>
|
||||||
|
</trim>
|
||||||
|
</if>
|
||||||
|
</foreach>
|
||||||
|
</where>
|
||||||
|
</sql>
|
||||||
|
<sql id="Update_By_Example_Where_Clause">
|
||||||
|
<where>
|
||||||
|
<foreach collection="example.oredCriteria" item="criteria" separator="or">
|
||||||
|
<if test="criteria.valid">
|
||||||
|
<trim prefix="(" prefixOverrides="and" suffix=")">
|
||||||
|
<foreach collection="criteria.criteria" item="criterion">
|
||||||
|
<choose>
|
||||||
|
<when test="criterion.noValue">
|
||||||
|
and ${criterion.condition}
|
||||||
|
</when>
|
||||||
|
<when test="criterion.singleValue">
|
||||||
|
AND ${criterion.condition} #{criterion.value}
|
||||||
|
</when>
|
||||||
|
<when test="criterion.betweenValue">
|
||||||
|
AND ${criterion.condition} #{criterion.value} AND #{criterion.secondValue}
|
||||||
|
</when>
|
||||||
|
<when test="criterion.listValue">
|
||||||
|
AND ${criterion.condition}
|
||||||
|
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
|
||||||
|
#{listItem}
|
||||||
|
</foreach>
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
</foreach>
|
||||||
|
</trim>
|
||||||
|
</if>
|
||||||
|
</foreach>
|
||||||
|
</where>
|
||||||
|
</sql>
|
||||||
|
<sql id="Base_Column_List">
|
||||||
|
id, user_id, access_key, secret_key, create_time, status
|
||||||
|
</sql>
|
||||||
|
<select id="selectByExample" parameterType="io.metersphere.base.domain.UserKeyExample" resultMap="BaseResultMap">
|
||||||
|
SELECT
|
||||||
|
<if test="distinct">
|
||||||
|
DISTINCT
|
||||||
|
</if>
|
||||||
|
<include refid="Base_Column_List" />
|
||||||
|
FROM user_key
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
<if test="orderByClause != null">
|
||||||
|
ORDER BY ${orderByClause}
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
|
||||||
|
SELECT
|
||||||
|
<include refid="Base_Column_List" />
|
||||||
|
FROM user_key
|
||||||
|
WHERE id = #{id,jdbcType=VARCHAR}
|
||||||
|
</select>
|
||||||
|
<delete id="deleteByPrimaryKey" parameterType="java.lang.String">
|
||||||
|
DELETE FROM user_key
|
||||||
|
WHERE id = #{id,jdbcType=VARCHAR}
|
||||||
|
</delete>
|
||||||
|
<delete id="deleteByExample" parameterType="io.metersphere.base.domain.UserKeyExample">
|
||||||
|
DELETE FROM user_key
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
</delete>
|
||||||
|
<insert id="insert" parameterType="io.metersphere.base.domain.UserKey">
|
||||||
|
INSERT INTO user_key (id, user_id, access_key,
|
||||||
|
secret_key, create_time, status
|
||||||
|
)
|
||||||
|
VALUES (#{id,jdbcType=VARCHAR}, #{userId,jdbcType=VARCHAR}, #{accessKey,jdbcType=VARCHAR},
|
||||||
|
#{secretKey,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{status,jdbcType=VARCHAR}
|
||||||
|
)
|
||||||
|
</insert>
|
||||||
|
<insert id="insertSelective" parameterType="io.metersphere.base.domain.UserKey">
|
||||||
|
INSERT INTO user_key
|
||||||
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="id != null">
|
||||||
|
id,
|
||||||
|
</if>
|
||||||
|
<if test="userId != null">
|
||||||
|
user_id,
|
||||||
|
</if>
|
||||||
|
<if test="accessKey != null">
|
||||||
|
access_key,
|
||||||
|
</if>
|
||||||
|
<if test="secretKey != null">
|
||||||
|
secret_key,
|
||||||
|
</if>
|
||||||
|
<if test="createTime != null">
|
||||||
|
create_time,
|
||||||
|
</if>
|
||||||
|
<if test="status != null">
|
||||||
|
status,
|
||||||
|
</if>
|
||||||
|
</trim>
|
||||||
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="id != null">
|
||||||
|
#{id,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="userId != null">
|
||||||
|
#{userId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="accessKey != null">
|
||||||
|
#{accessKey,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="secretKey != null">
|
||||||
|
#{secretKey,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="createTime != null">
|
||||||
|
#{createTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="status != null">
|
||||||
|
#{status,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
</trim>
|
||||||
|
</insert>
|
||||||
|
<select id="countByExample" parameterType="io.metersphere.base.domain.UserKeyExample" resultType="java.lang.Long">
|
||||||
|
SELECT count(*) FROM user_key
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
<update id="updateByExampleSelective" parameterType="map">
|
||||||
|
UPDATE user_key
|
||||||
|
<set>
|
||||||
|
<if test="record.id != null">
|
||||||
|
id = #{record.id,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.userId != null">
|
||||||
|
user_id = #{record.userId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.accessKey != null">
|
||||||
|
access_key = #{record.accessKey,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.secretKey != null">
|
||||||
|
secret_key = #{record.secretKey,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="record.createTime != null">
|
||||||
|
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="record.status != null">
|
||||||
|
status = #{record.status,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
</set>
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
</update>
|
||||||
|
<update id="updateByExample" parameterType="map">
|
||||||
|
UPDATE user_key
|
||||||
|
SET id = #{record.id,jdbcType=VARCHAR},
|
||||||
|
user_id = #{record.userId,jdbcType=VARCHAR},
|
||||||
|
access_key = #{record.accessKey,jdbcType=VARCHAR},
|
||||||
|
secret_key = #{record.secretKey,jdbcType=VARCHAR},
|
||||||
|
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||||
|
status = #{record.status,jdbcType=VARCHAR}
|
||||||
|
<if test="_parameter != null">
|
||||||
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
|
</if>
|
||||||
|
</update>
|
||||||
|
<update id="updateByPrimaryKeySelective" parameterType="io.metersphere.base.domain.UserKey">
|
||||||
|
UPDATE user_key
|
||||||
|
<set>
|
||||||
|
<if test="userId != null">
|
||||||
|
user_id = #{userId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="accessKey != null">
|
||||||
|
access_key = #{accessKey,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="secretKey != null">
|
||||||
|
secret_key = #{secretKey,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="createTime != null">
|
||||||
|
create_time = #{createTime,jdbcType=BIGINT},
|
||||||
|
</if>
|
||||||
|
<if test="status != null">
|
||||||
|
status = #{status,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
</set>
|
||||||
|
WHERE id = #{id,jdbcType=VARCHAR}
|
||||||
|
</update>
|
||||||
|
<update id="updateByPrimaryKey" parameterType="io.metersphere.base.domain.UserKey">
|
||||||
|
UPDATE user_key
|
||||||
|
SET user_id = #{userId,jdbcType=VARCHAR},
|
||||||
|
access_key = #{accessKey,jdbcType=VARCHAR},
|
||||||
|
secret_key = #{secretKey,jdbcType=VARCHAR},
|
||||||
|
create_time = #{createTime,jdbcType=BIGINT},
|
||||||
|
status = #{status,jdbcType=VARCHAR}
|
||||||
|
WHERE id = #{id,jdbcType=VARCHAR}
|
||||||
|
</update>
|
||||||
|
</mapper>
|
|
@ -0,0 +1,5 @@
|
||||||
|
package io.metersphere.commons.constants;
|
||||||
|
|
||||||
|
public enum ApiKeyConstants {
|
||||||
|
ACTIVE, DISABLED
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package io.metersphere.config;
|
package io.metersphere.config;
|
||||||
|
|
||||||
|
import io.metersphere.security.ApiKeyFilter;
|
||||||
import io.metersphere.security.LoginFilter;
|
import io.metersphere.security.LoginFilter;
|
||||||
import io.metersphere.security.ShiroDBRealm;
|
import io.metersphere.security.ShiroDBRealm;
|
||||||
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
|
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
|
||||||
|
@ -37,6 +38,7 @@ public class ShiroConfig {
|
||||||
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
|
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
|
||||||
shiroFilterFactoryBean.setSuccessUrl("/");
|
shiroFilterFactoryBean.setSuccessUrl("/");
|
||||||
|
|
||||||
|
shiroFilterFactoryBean.getFilters().put("apikey", new ApiKeyFilter());
|
||||||
|
|
||||||
Map<String, String> filterChainDefinitionMap = shiroFilterFactoryBean.getFilterChainDefinitionMap();
|
Map<String, String> filterChainDefinitionMap = shiroFilterFactoryBean.getFilterChainDefinitionMap();
|
||||||
filterChainDefinitionMap.put("/resource/**", "anon");
|
filterChainDefinitionMap.put("/resource/**", "anon");
|
||||||
|
@ -51,7 +53,7 @@ public class ShiroConfig {
|
||||||
filterChainDefinitionMap.put("/api/**", "anon");
|
filterChainDefinitionMap.put("/api/**", "anon");
|
||||||
filterChainDefinitionMap.put("/403", "anon");
|
filterChainDefinitionMap.put("/403", "anon");
|
||||||
filterChainDefinitionMap.put("/anonymous/**", "anon");
|
filterChainDefinitionMap.put("/anonymous/**", "anon");
|
||||||
filterChainDefinitionMap.put("/**", "authc");
|
filterChainDefinitionMap.put("/**", "apikey, authc");
|
||||||
return shiroFilterFactoryBean;
|
return shiroFilterFactoryBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package io.metersphere.controller;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.UserKey;
|
||||||
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
|
import io.metersphere.service.UserKeyService;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("user/key")
|
||||||
|
public class UserKeysController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private UserKeyService userKeyService;
|
||||||
|
|
||||||
|
@GetMapping("info")
|
||||||
|
public List<UserKey> getUserKeysInfo() {
|
||||||
|
String userId = SessionUtils.getUser().getId();
|
||||||
|
return userKeyService.getUserKeysInfo(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("generate")
|
||||||
|
public void generateUserKey() {
|
||||||
|
String userId = SessionUtils.getUser().getId();
|
||||||
|
userKeyService.generateUserKey(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("delete/{id}")
|
||||||
|
public void deleteUserKey(@PathVariable String id) {
|
||||||
|
userKeyService.deleteUserKey(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("active/{id}")
|
||||||
|
public void activeUserKey(@PathVariable String id) {
|
||||||
|
userKeyService.activeUserKey(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("disable/{id}")
|
||||||
|
public void disabledUserKey(@PathVariable String id) {
|
||||||
|
userKeyService.disableUserKey(id);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package io.metersphere.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class ScheduleDTO {
|
||||||
|
private Boolean enable;
|
||||||
|
private String cronExpression;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package io.metersphere.schedule.job;
|
||||||
|
|
||||||
|
import io.metersphere.api.service.APITestService;
|
||||||
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
|
import org.quartz.Job;
|
||||||
|
import org.quartz.JobExecutionContext;
|
||||||
|
import org.quartz.JobExecutionException;
|
||||||
|
|
||||||
|
public class ApiTestJob implements Job {
|
||||||
|
|
||||||
|
private APITestService apiTestService;
|
||||||
|
|
||||||
|
public ApiTestJob() {
|
||||||
|
apiTestService = (APITestService) CommonBeanFactory.getBean("apiTestService");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(JobExecutionContext context) throws JobExecutionException {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package io.metersphere.security;
|
||||||
|
|
||||||
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.shiro.SecurityUtils;
|
||||||
|
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||||
|
import org.apache.shiro.web.filter.authc.AnonymousFilter;
|
||||||
|
import org.apache.shiro.web.util.WebUtils;
|
||||||
|
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
public class ApiKeyFilter extends AnonymousFilter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) {
|
||||||
|
try {
|
||||||
|
if (!SecurityUtils.getSubject().isAuthenticated()) {
|
||||||
|
String userId = ApiKeyHandler.getUser(WebUtils.toHttp(request));
|
||||||
|
if (StringUtils.isNotBlank(userId)) {
|
||||||
|
if (LogUtil.getLogger().isDebugEnabled()) {
|
||||||
|
LogUtil.getLogger().debug("user auth: " + userId);
|
||||||
|
}
|
||||||
|
SecurityUtils.getSubject().login(new UsernamePasswordToken(userId, ApiKeySessionHandler.random));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ApiKeyHandler.isApiKeyCall(WebUtils.toHttp(request))) {
|
||||||
|
String userId = ApiKeyHandler.getUser(WebUtils.toHttp(request));
|
||||||
|
SecurityUtils.getSubject().login(new UsernamePasswordToken(userId, ApiKeySessionHandler.random));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SecurityUtils.getSubject().isAuthenticated()) {
|
||||||
|
((HttpServletResponse) response).setHeader("Authentication-Status", "invalid");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (ApiKeyHandler.isApiKeyCall(WebUtils.toHttp(request))) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
LogUtil.getLogger().error("failed to handle single sign on..", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package io.metersphere.security;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.UserKey;
|
||||||
|
import io.metersphere.commons.utils.CodingUtil;
|
||||||
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
|
import io.metersphere.service.UserKeyService;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
public class ApiKeyHandler {
|
||||||
|
|
||||||
|
public static final String API_ACCESS_KEY = "accessKey";
|
||||||
|
|
||||||
|
public static final String API_SIGNATURE = "signature";
|
||||||
|
|
||||||
|
public static String getUser(HttpServletRequest request) {
|
||||||
|
if (request == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return getUser(request.getHeader(API_ACCESS_KEY), request.getHeader(API_SIGNATURE));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean isApiKeyCall(HttpServletRequest request) {
|
||||||
|
if (request == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !StringUtils.isBlank(request.getHeader(API_ACCESS_KEY)) && !StringUtils.isBlank(request.getHeader(API_SIGNATURE));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getUser(String accessKey, String signature) {
|
||||||
|
if (StringUtils.isBlank(accessKey) || StringUtils.isBlank(signature)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
UserKey userKey = CommonBeanFactory.getBean(UserKeyService.class).getUserKey(accessKey);
|
||||||
|
if (userKey == null) {
|
||||||
|
throw new RuntimeException("invalid accessKey");
|
||||||
|
}
|
||||||
|
String signatureDecrypt;
|
||||||
|
try {
|
||||||
|
signatureDecrypt = CodingUtil.aesDecrypt(signature, userKey.getSecretKey(), accessKey);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
throw new RuntimeException("invalid signature");
|
||||||
|
}
|
||||||
|
String[] signatureArray = StringUtils.split(StringUtils.trimToNull(signatureDecrypt), "|");
|
||||||
|
if (signatureArray.length < 2) {
|
||||||
|
throw new RuntimeException("invalid signature");
|
||||||
|
}
|
||||||
|
if (!StringUtils.equals(accessKey, signatureArray[0])) {
|
||||||
|
throw new RuntimeException("invalid signature");
|
||||||
|
}
|
||||||
|
long signatureTime;
|
||||||
|
try {
|
||||||
|
signatureTime = Long.parseLong(signatureArray[signatureArray.length - 1]);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
if (Math.abs(System.currentTimeMillis() - signatureTime) > 1800000) {
|
||||||
|
//签名30分钟超时
|
||||||
|
throw new RuntimeException("expired signature");
|
||||||
|
}
|
||||||
|
return userKey.getUserId();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package io.metersphere.security;
|
||||||
|
|
||||||
|
import io.metersphere.commons.utils.EncryptUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
||||||
|
public class ApiKeySessionHandler {
|
||||||
|
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(ApiKeySessionHandler.class);
|
||||||
|
|
||||||
|
|
||||||
|
public static String random = UUID.randomUUID().toString() + UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
public static String generateId(String authInfo) {
|
||||||
|
return SessionGenerator.generateId(authInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String validate(HttpServletRequest request) {
|
||||||
|
try {
|
||||||
|
String v = request.getHeader(ApiKeyHandler.API_SIGNATURE);
|
||||||
|
if (StringUtils.isNotBlank(v)) {
|
||||||
|
return SessionGenerator.fromId(v);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("failed to validate", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class SessionGenerator {
|
||||||
|
public SessionGenerator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String generateId(String authInfo) {
|
||||||
|
return EncryptUtils.aesEncrypt(parse2Str(authInfo)).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String fromId(String sessionId) {
|
||||||
|
String authInfoString = EncryptUtils.aesDecrypt(sessionId).toString();
|
||||||
|
return fromStr(authInfoString);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String parse2Str(String authInfo) {
|
||||||
|
return UUID.randomUUID().toString() + "|" + authInfo + "|" + System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String fromStr(String authInfoString) {
|
||||||
|
String[] sp = authInfoString.split("\\|");
|
||||||
|
return sp[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -83,6 +83,12 @@ public class ShiroDBRealm extends AuthorizingRealm {
|
||||||
SessionUtils.putUser(sessionUser);
|
SessionUtils.putUser(sessionUser);
|
||||||
return new SimpleAuthenticationInfo(userId, password, getName());
|
return new SimpleAuthenticationInfo(userId, password, getName());
|
||||||
}
|
}
|
||||||
|
// apikey 校验不验证密码
|
||||||
|
if (ApiKeySessionHandler.random.equalsIgnoreCase(password)) {
|
||||||
|
SessionUser sessionUser = SessionUser.fromUser(user);
|
||||||
|
SessionUtils.putUser(sessionUser);
|
||||||
|
return new SimpleAuthenticationInfo(userId, password, getName());
|
||||||
|
}
|
||||||
// 密码验证
|
// 密码验证
|
||||||
if (!userService.checkUserPassword(userId, password)) {
|
if (!userService.checkUserPassword(userId, password)) {
|
||||||
throw new IncorrectCredentialsException(Translator.get("password_is_incorrect"));
|
throw new IncorrectCredentialsException(Translator.get("password_is_incorrect"));
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
package io.metersphere.service;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.UserKey;
|
||||||
|
import io.metersphere.base.domain.UserKeyExample;
|
||||||
|
import io.metersphere.base.mapper.UserKeyMapper;
|
||||||
|
import io.metersphere.commons.constants.ApiKeyConstants;
|
||||||
|
import io.metersphere.commons.exception.MSException;
|
||||||
|
import io.metersphere.i18n.Translator;
|
||||||
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class UserKeyService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private UserKeyMapper userKeyMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
|
public List<UserKey> getUserKeysInfo(String userId) {
|
||||||
|
UserKeyExample userKeysExample = new UserKeyExample();
|
||||||
|
userKeysExample.createCriteria().andUserIdEqualTo(userId);
|
||||||
|
userKeysExample.setOrderByClause("create_time");
|
||||||
|
return userKeyMapper.selectByExample(userKeysExample);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserKey generateUserKey(String userId) {
|
||||||
|
if (userService.getUserDTO(userId) == null) {
|
||||||
|
MSException.throwException(Translator.get("user_not_exist") + userId);
|
||||||
|
}
|
||||||
|
UserKeyExample userKeysExample = new UserKeyExample();
|
||||||
|
userKeysExample.createCriteria().andUserIdEqualTo(userId);
|
||||||
|
List<UserKey> userKeysList = userKeyMapper.selectByExample(userKeysExample);
|
||||||
|
|
||||||
|
if (!CollectionUtils.isEmpty(userKeysList) && userKeysList.size() >= 5) {
|
||||||
|
MSException.throwException(Translator.get("user_apikey_limit"));
|
||||||
|
}
|
||||||
|
|
||||||
|
UserKey userKeys = new UserKey();
|
||||||
|
userKeys.setId(UUID.randomUUID().toString());
|
||||||
|
userKeys.setUserId(userId);
|
||||||
|
userKeys.setStatus(ApiKeyConstants.ACTIVE.name());
|
||||||
|
userKeys.setAccessKey(RandomStringUtils.randomAlphanumeric(16));
|
||||||
|
userKeys.setSecretKey(RandomStringUtils.randomAlphanumeric(16));
|
||||||
|
userKeys.setCreateTime(System.currentTimeMillis());
|
||||||
|
userKeyMapper.insert(userKeys);
|
||||||
|
return userKeyMapper.selectByPrimaryKey(userKeys.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteUserKey(String id) {
|
||||||
|
userKeyMapper.deleteByPrimaryKey(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void activeUserKey(String id) {
|
||||||
|
UserKey userKeys = new UserKey();
|
||||||
|
userKeys.setId(id);
|
||||||
|
userKeys.setStatus(ApiKeyConstants.ACTIVE.name());
|
||||||
|
userKeyMapper.updateByPrimaryKeySelective(userKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disableUserKey(String id) {
|
||||||
|
UserKey userKeys = new UserKey();
|
||||||
|
userKeys.setId(id);
|
||||||
|
userKeys.setStatus(ApiKeyConstants.DISABLED.name());
|
||||||
|
userKeyMapper.updateByPrimaryKeySelective(userKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserKey getUserKey(String accessKey) {
|
||||||
|
UserKeyExample userKeyExample = new UserKeyExample();
|
||||||
|
userKeyExample.createCriteria().andAccessKeyEqualTo(accessKey).andStatusEqualTo(ApiKeyConstants.ACTIVE.name());
|
||||||
|
List<UserKey> userKeysList = userKeyMapper.selectByExample(userKeyExample);
|
||||||
|
if (!CollectionUtils.isEmpty(userKeysList)) {
|
||||||
|
return userKeysList.get(0);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
CREATE TABLE `user_key` (
|
||||||
|
`id` varchar(50) NOT NULL DEFAULT '' COMMENT 'user_key ID',
|
||||||
|
`user_id` varchar(50) NOT NULL COMMENT '用户ID',
|
||||||
|
`access_key` varchar(50) NOT NULL COMMENT 'access_key',
|
||||||
|
`secret_key` varchar(50) NOT NULL COMMENT 'secret key',
|
||||||
|
`create_time` bigint(13) NOT NULL COMMENT '创建时间',
|
||||||
|
`status` varchar(10) DEFAULT NULL COMMENT '状态',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `IDX_AK` (`access_key`),
|
||||||
|
KEY `IDX_USER_ID` (`user_id`)
|
||||||
|
)
|
||||||
|
ENGINE = InnoDB
|
||||||
|
DEFAULT CHARSET = utf8mb4;
|
||||||
|
|
|
@ -27,6 +27,7 @@ user_locked=the user has been locked.
|
||||||
user_expires=user expires.
|
user_expires=user expires.
|
||||||
not_authorized=not authorized.
|
not_authorized=not authorized.
|
||||||
login_fail=Login fail
|
login_fail=Login fail
|
||||||
|
user_apikey_limit=Can have up to 5 api keys
|
||||||
#load test
|
#load test
|
||||||
edit_load_test_not_found=Cannot edit test, test not found=
|
edit_load_test_not_found=Cannot edit test, test not found=
|
||||||
run_load_test_not_found=Cannot run test, test not found=
|
run_load_test_not_found=Cannot run test, test not found=
|
||||||
|
|
|
@ -27,6 +27,7 @@ excessive_attempts=操作频繁
|
||||||
user_locked=用户被锁定
|
user_locked=用户被锁定
|
||||||
user_expires=用户过期
|
user_expires=用户过期
|
||||||
not_authorized=未经授权
|
not_authorized=未经授权
|
||||||
|
user_apikey_limit=最多能有5个Api key
|
||||||
#load test
|
#load test
|
||||||
edit_load_test_not_found=无法编辑测试,未找到测试:
|
edit_load_test_not_found=无法编辑测试,未找到测试:
|
||||||
run_load_test_not_found=无法运行测试,未找到测试:
|
run_load_test_not_found=无法运行测试,未找到测试:
|
||||||
|
|
|
@ -27,6 +27,7 @@ user_locked=用戶被鎖定
|
||||||
user_expires=用戶過期
|
user_expires=用戶過期
|
||||||
not_authorized=未經授權。
|
not_authorized=未經授權。
|
||||||
login_fail=登入失敗
|
login_fail=登入失敗
|
||||||
|
user_apikey_limit=最多能有5個Api key
|
||||||
#load test
|
#load test
|
||||||
edit_load_test_not_found=無法編輯測試,未找到測試:
|
edit_load_test_not_found=無法編輯測試,未找到測試:
|
||||||
run_load_test_not_found=無法運行測試,未找到測試:
|
run_load_test_not_found=無法運行測試,未找到測試:
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -48,7 +48,9 @@
|
||||||
"rules": {
|
"rules": {
|
||||||
"vue/no-unused-components": "off",
|
"vue/no-unused-components": "off",
|
||||||
"no-console": "off",
|
"no-console": "off",
|
||||||
"no-unused-vars": "off"
|
"no-unused-vars": "off",
|
||||||
|
"no-unused-expressions": "off",
|
||||||
|
"no-unused-labels": "off"
|
||||||
},
|
},
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"parser": "babel-eslint"
|
"parser": "babel-eslint"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<el-card>
|
<el-card>
|
||||||
<el-container class="test-container" v-loading="result.loading">
|
<el-container class="test-container" v-loading="result.loading">
|
||||||
<el-header>
|
<el-header>
|
||||||
<el-row type="flex" align="middle">
|
<el-row>
|
||||||
<el-input :disabled="isReadOnly" class="test-name" v-model="test.name" maxlength="60"
|
<el-input :disabled="isReadOnly" class="test-name" v-model="test.name" maxlength="60"
|
||||||
:placeholder="$t('api_test.input_name')"
|
:placeholder="$t('api_test.input_name')"
|
||||||
show-word-limit>
|
show-word-limit>
|
||||||
|
@ -46,6 +46,8 @@
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
|
|
||||||
<ms-api-report-dialog :test-id="id" ref="reportDialog"/>
|
<ms-api-report-dialog :test-id="id" ref="reportDialog"/>
|
||||||
|
|
||||||
|
<ms-schedule-config :schedule="test.schedule" :save="saveCronExpression" @scheduleChange="saveSchedule" :check-open="checkScheduleEdit"/>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-header>
|
</el-header>
|
||||||
<ms-api-scenario-config :is-read-only="isReadOnly" :scenarios="test.scenarioDefinition" ref="config"/>
|
<ms-api-scenario-config :is-read-only="isReadOnly" :scenarios="test.scenarioDefinition" ref="config"/>
|
||||||
|
@ -61,11 +63,12 @@
|
||||||
import MsApiReportStatus from "../report/ApiReportStatus";
|
import MsApiReportStatus from "../report/ApiReportStatus";
|
||||||
import MsApiReportDialog from "./ApiReportDialog";
|
import MsApiReportDialog from "./ApiReportDialog";
|
||||||
import {checkoutTestManagerOrTestUser, downloadFile} from "../../../../common/js/utils";
|
import {checkoutTestManagerOrTestUser, downloadFile} from "../../../../common/js/utils";
|
||||||
|
import MsScheduleConfig from "../../common/components/MsScheduleConfig";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsApiTestConfig",
|
name: "MsApiTestConfig",
|
||||||
|
|
||||||
components: {MsApiReportDialog, MsApiReportStatus, MsApiScenarioConfig},
|
components: {MsScheduleConfig, MsApiReportDialog, MsApiReportStatus, MsApiScenarioConfig},
|
||||||
|
|
||||||
props: ["id"],
|
props: ["id"],
|
||||||
|
|
||||||
|
@ -126,6 +129,7 @@
|
||||||
name: item.name,
|
name: item.name,
|
||||||
status: item.status,
|
status: item.status,
|
||||||
scenarioDefinition: JSON.parse(item.scenarioDefinition),
|
scenarioDefinition: JSON.parse(item.scenarioDefinition),
|
||||||
|
schedule: item.schedule ? JSON.parse(item.schedule) : {},
|
||||||
});
|
});
|
||||||
this.$refs.config.reset();
|
this.$refs.config.reset();
|
||||||
}
|
}
|
||||||
|
@ -208,6 +212,31 @@
|
||||||
downloadFile(this.test.name + ".json", this.test.export());
|
downloadFile(this.test.name + ".json", this.test.export());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
saveCronExpression(cronExpression) {
|
||||||
|
this.test.schedule.enable = true;
|
||||||
|
this.test.schedule.cronExpression = cronExpression;
|
||||||
|
this.saveSchedule();
|
||||||
|
},
|
||||||
|
saveSchedule() {
|
||||||
|
if (this.create) {
|
||||||
|
this.$message('请先保存测试,在设置定时任务');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let param = {};
|
||||||
|
param.id = this.test.id;
|
||||||
|
param.schedule = this.test.schedule;
|
||||||
|
this.$post('/api/schedule/update', param, response => {
|
||||||
|
this.$success('保存成功');
|
||||||
|
this.getTest(this.test.id);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
checkScheduleEdit() {
|
||||||
|
if (this.create) {
|
||||||
|
this.$message('请先保存测试');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -245,4 +274,8 @@
|
||||||
.test-container .more {
|
.test-container .more {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.schedule-config {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -100,6 +100,7 @@ export class Test extends BaseConfig {
|
||||||
this.name = undefined;
|
this.name = undefined;
|
||||||
this.projectId = undefined;
|
this.projectId = undefined;
|
||||||
this.scenarioDefinition = [];
|
this.scenarioDefinition = [];
|
||||||
|
this.schedule = {};
|
||||||
|
|
||||||
this.set(options);
|
this.set(options);
|
||||||
this.sets({scenarioDefinition: Scenario}, options);
|
this.sets({scenarioDefinition: Scenario}, options);
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
<template>
|
||||||
|
<div class="schedule-config">
|
||||||
|
<div>
|
||||||
|
<span class="cron-ico">
|
||||||
|
<i class="el-icon-date" size="small"></i>
|
||||||
|
<span class="character" @click="scheduleEdit">SCHEDULER</span>
|
||||||
|
</span>
|
||||||
|
<el-switch :disabled="!schedule.cronExpression" v-model="schedule.enable" @change="scheduleChange"/>
|
||||||
|
<ms-schedule-edit :schedule="schedule" :save="save" ref="scheduleEdit"/>
|
||||||
|
<crontab-result v-show="false" :ex="schedule.cronExpression" ref="crontabResult" @resultListChange="recentListChange"/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span :class="{'disable-character': !schedule.enable}"> 下次执行时间:{{this.recentList.length > 0 ? this.recentList[0] : ''}} </span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MsScheduleEdit from "./MsScheduleEdit";
|
||||||
|
import CrontabResult from "../cron/CrontabResult";
|
||||||
|
export default {
|
||||||
|
name: "MsScheduleConfig",
|
||||||
|
components: {CrontabResult, MsScheduleEdit},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
recentList: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
save: Function,
|
||||||
|
schedule: {},
|
||||||
|
checkOpen: {
|
||||||
|
type: Function,
|
||||||
|
default() {
|
||||||
|
return new Function()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// mounted() {
|
||||||
|
// console.log(this.schedule);
|
||||||
|
// // this.recentList = this.$refs.crontabResult.resultList;
|
||||||
|
// // console.log(this.recentList);
|
||||||
|
// console.log(this.recentList+ "====");
|
||||||
|
// },
|
||||||
|
// watch: {
|
||||||
|
// 'schedule.cronExpression'() {
|
||||||
|
// console.log(this.schedule);
|
||||||
|
// this.$refs.crontabResult.expressionChange();
|
||||||
|
// this.recentList = this.$refs.crontabResult.resultList;
|
||||||
|
// console.log(this.recentList);
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
methods: {
|
||||||
|
scheduleEdit() {
|
||||||
|
if (!this.checkOpen()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$refs.scheduleEdit.open();
|
||||||
|
},
|
||||||
|
scheduleChange() {
|
||||||
|
this.$emit('scheduleChange');
|
||||||
|
},
|
||||||
|
recentListChange(resultList) {
|
||||||
|
this.recentList = resultList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
.schedule-config {
|
||||||
|
float: right;
|
||||||
|
width: 250px;
|
||||||
|
height: 15px;
|
||||||
|
line-height: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-icon-date {
|
||||||
|
font-size: 20px;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character {
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disable-character {
|
||||||
|
color: #cccccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-switch {
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cron-ico {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,97 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog width="30%" class="schedule-edit" :title="'编辑定时任务'" :visible.sync="dialogVisible" @close="close">
|
||||||
|
<div id="app">
|
||||||
|
<el-form :model="form" :rules="rules" ref="from">
|
||||||
|
<el-form-item
|
||||||
|
:placeholder="'请输入 Cron 表达式'"
|
||||||
|
prop="cronValue">
|
||||||
|
<el-input v-model="form.cronValue" placeholder class="inp"/>
|
||||||
|
<el-button type="primary" @click="showCronDialog">生成 Cron</el-button>
|
||||||
|
<el-button type="primary" @click="saveCron">保存</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
<crontab-result :ex="schedule.cronExpression" ref="crontabResult"/>
|
||||||
|
</el-form>
|
||||||
|
<el-dialog title="生成 cron" :visible.sync="showCron" :modal="false">
|
||||||
|
<crontab @hide="showCron=false" @fill="crontabFill" :expression="schedule.cronExpression"/>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import Crontab from "../cron/Crontab";
|
||||||
|
import CrontabResult from "../cron/CrontabResult";
|
||||||
|
import {cronValidate} from "../../../../common/js/cron";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "MsScheduleEdit",
|
||||||
|
components: {CrontabResult, Crontab},
|
||||||
|
props: {
|
||||||
|
save: Function,
|
||||||
|
schedule: {},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'schedule.cronExpression'() {
|
||||||
|
this.form.cronValue = this.schedule.cronExpression;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
const validateCron = (rule, cronValue, callback) => {
|
||||||
|
if (!cronValidate(cronValue)) {
|
||||||
|
callback(new Error('Cron 表达式格式错误'));
|
||||||
|
} else {
|
||||||
|
this.schedule.cronExpression = cronValue;
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
dialogVisible: false,
|
||||||
|
showCron: false,
|
||||||
|
form: {
|
||||||
|
cronValue: ""
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
cronValue :[{required: true, validator: validateCron, trigger: 'blur'}],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
open() {
|
||||||
|
this.dialogVisible = true;
|
||||||
|
},
|
||||||
|
crontabFill(value) {
|
||||||
|
//确定后回传的值
|
||||||
|
this.schedule.cronExpression = value;
|
||||||
|
this.form.cronValue = value;
|
||||||
|
this.$refs['from'].validate();
|
||||||
|
},
|
||||||
|
showCronDialog() {
|
||||||
|
this.showCron = true;
|
||||||
|
},
|
||||||
|
saveCron () {
|
||||||
|
this.$refs['from'].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.save(this.form.cronValue);
|
||||||
|
this.dialogVisible = false;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
this.$refs['from'].resetFields();
|
||||||
|
this.$refs.crontabResult.resultList = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
.inp {
|
||||||
|
width: 50%;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,422 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-tabs type="border-card">
|
||||||
|
<el-tab-pane label="秒" v-if="shouldHide('second')">
|
||||||
|
<crontab-second
|
||||||
|
@update="updateContabValue"
|
||||||
|
:check="checkNumber"
|
||||||
|
ref="cronsecond"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="分钟" v-if="shouldHide('min')">
|
||||||
|
<crontab-min
|
||||||
|
@update="updateContabValue"
|
||||||
|
:check="checkNumber"
|
||||||
|
:cron="contabValueObj"
|
||||||
|
ref="cronmin"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="小时" v-if="shouldHide('hour')">
|
||||||
|
<crontab-hour
|
||||||
|
@update="updateContabValue"
|
||||||
|
:check="checkNumber"
|
||||||
|
:cron="contabValueObj"
|
||||||
|
ref="cronhour"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="日" v-if="shouldHide('day')">
|
||||||
|
<crontab-day
|
||||||
|
@update="updateContabValue"
|
||||||
|
:check="checkNumber"
|
||||||
|
:cron="contabValueObj"
|
||||||
|
ref="cronday"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="月" v-if="shouldHide('mouth')">
|
||||||
|
<crontab-mouth
|
||||||
|
@update="updateContabValue"
|
||||||
|
:check="checkNumber"
|
||||||
|
:cron="contabValueObj"
|
||||||
|
ref="cronmouth"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="周" v-if="shouldHide('week')">
|
||||||
|
<crontab-week
|
||||||
|
@update="updateContabValue"
|
||||||
|
:check="checkNumber"
|
||||||
|
:cron="contabValueObj"
|
||||||
|
ref="cronweek"
|
||||||
|
/>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="年" v-if="shouldHide('year')">
|
||||||
|
<crontab-year @update="updateContabValue"
|
||||||
|
:check="checkNumber"
|
||||||
|
:cron="contabValueObj"
|
||||||
|
ref="cronyear"/>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
|
||||||
|
<div class="popup-main">
|
||||||
|
<div class="popup-result-container">
|
||||||
|
<p class="title">时间表达式</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<th v-for="item of tabTitles" width="40" :key="item">{{item}}</th>
|
||||||
|
<th>crontab完整表达式</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<td>
|
||||||
|
<span>{{contabValueObj.second}}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span>{{contabValueObj.min}}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span>{{contabValueObj.hour}}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span>{{contabValueObj.day}}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span>{{contabValueObj.mouth}}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span>{{contabValueObj.week}}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span>{{contabValueObj.year}}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span>{{contabValueString}}</span>
|
||||||
|
</td>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<crontab-result :ex="contabValueString"/>
|
||||||
|
|
||||||
|
<div class="pop_btn">
|
||||||
|
<el-button size="small" type="primary" @click="submitFill">确定</el-button>
|
||||||
|
<el-button size="small" type="warning" @click="clearCron">重置</el-button>
|
||||||
|
<el-button size="small" @click="hidePopup">取消</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import CrontabSecond from "./CrontabSecond.vue";
|
||||||
|
import CrontabMin from "./CrontabMin.vue";
|
||||||
|
import CrontabHour from "./CrontabHour.vue";
|
||||||
|
import CrontabDay from "./CrontabDay.vue";
|
||||||
|
import CrontabMouth from "./CrontabMouth.vue";
|
||||||
|
import CrontabWeek from "./CrontabWeek.vue";
|
||||||
|
import CrontabYear from "./CrontabYear.vue";
|
||||||
|
import CrontabResult from "./CrontabResult.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Crontab",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
tabTitles: ["秒", "分钟", "小时", "日", "月", "周", "年"],
|
||||||
|
tabActive: 0,
|
||||||
|
myindex: 0,
|
||||||
|
contabValueObj: {
|
||||||
|
second: "*",
|
||||||
|
min: "*",
|
||||||
|
hour: "*",
|
||||||
|
day: "*",
|
||||||
|
mouth: "*",
|
||||||
|
week: "?",
|
||||||
|
year: "",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: ["expression", "hideComponent"],
|
||||||
|
methods: {
|
||||||
|
shouldHide(key) {
|
||||||
|
if (this.hideComponent && this.hideComponent.includes(key)) return false;
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
resolveExp() {
|
||||||
|
//反解析 表达式
|
||||||
|
if (this.expression) {
|
||||||
|
let arr = this.expression.split(" ");
|
||||||
|
if (arr.length >= 6) {
|
||||||
|
//6 位以上是合法表达式
|
||||||
|
let obj = {
|
||||||
|
second: arr[0],
|
||||||
|
min: arr[1],
|
||||||
|
hour: arr[2],
|
||||||
|
day: arr[3],
|
||||||
|
mouth: arr[4],
|
||||||
|
week: arr[5],
|
||||||
|
year: arr[6] ? arr[6] : "",
|
||||||
|
};
|
||||||
|
this.contabValueObj = {
|
||||||
|
...obj,
|
||||||
|
};
|
||||||
|
for (let i in obj) {
|
||||||
|
if (obj[i]) this.changeRadio(i, obj[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//没有传入的表达式 则还原
|
||||||
|
this.clearCron();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// tab切换值
|
||||||
|
tabCheck(index) {
|
||||||
|
this.tabActive = index;
|
||||||
|
},
|
||||||
|
// 由子组件触发,更改表达式组成的字段值
|
||||||
|
updateContabValue(name, value, from) {
|
||||||
|
"updateContabValue", name, value, from;
|
||||||
|
this.contabValueObj[name] = value;
|
||||||
|
if (from && from !== name) {
|
||||||
|
console.log(`来自组件 ${from} 改变了 ${name} ${value}`);
|
||||||
|
this.changeRadio(name, value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//赋值到组件
|
||||||
|
changeRadio(name, value) {
|
||||||
|
let arr = ["second", "min", "hour", "mouth"],
|
||||||
|
refName = "cron" + name,
|
||||||
|
insVlaue;
|
||||||
|
|
||||||
|
if (!this.$refs[refName]) return;
|
||||||
|
|
||||||
|
if (arr.includes(name)) {
|
||||||
|
if (value === "*") {
|
||||||
|
insVlaue = 1;
|
||||||
|
} else if (value.indexOf("-") > -1) {
|
||||||
|
let indexArr = value.split("-");
|
||||||
|
isNaN(indexArr[0])
|
||||||
|
? (this.$refs[refName].cycle01 = 0)
|
||||||
|
: (this.$refs[refName].cycle01 = indexArr[0]);
|
||||||
|
this.$refs[refName].cycle02 = indexArr[1];
|
||||||
|
insVlaue = 2;
|
||||||
|
} else if (value.indexOf("/") > -1) {
|
||||||
|
let indexArr = value.split("/");
|
||||||
|
isNaN(indexArr[0])
|
||||||
|
? (this.$refs[refName].average01 = 0)
|
||||||
|
: (this.$refs[refName].average01 = indexArr[0]);
|
||||||
|
this.$refs[refName].average02 = indexArr[1];
|
||||||
|
insVlaue = 3;
|
||||||
|
} else {
|
||||||
|
insVlaue = 4;
|
||||||
|
this.$refs[refName].checkboxList = value.split(",");
|
||||||
|
}
|
||||||
|
} else if (name == "day") {
|
||||||
|
if (value === "*") {
|
||||||
|
insVlaue = 1;
|
||||||
|
} else if (value == "?") {
|
||||||
|
insVlaue = 2;
|
||||||
|
} else if (value.indexOf("-") > -1) {
|
||||||
|
let indexArr = value.split("-");
|
||||||
|
isNaN(indexArr[0])
|
||||||
|
? (this.$refs[refName].cycle01 = 0)
|
||||||
|
: (this.$refs[refName].cycle01 = indexArr[0]);
|
||||||
|
this.$refs[refName].cycle02 = indexArr[1];
|
||||||
|
insVlaue = 3;
|
||||||
|
} else if (value.indexOf("/") > -1) {
|
||||||
|
let indexArr = value.split("/");
|
||||||
|
isNaN(indexArr[0])
|
||||||
|
? (this.$refs[refName].average01 = 0)
|
||||||
|
: (this.$refs[refName].average01 = indexArr[0]);
|
||||||
|
this.$refs[refName].average02 = indexArr[1];
|
||||||
|
insVlaue = 4;
|
||||||
|
} else if (value.indexOf("W") > -1) {
|
||||||
|
let indexArr = value.split("W");
|
||||||
|
isNaN(indexArr[0])
|
||||||
|
? (this.$refs[refName].workday = 0)
|
||||||
|
: (this.$refs[refName].workday = indexArr[0]);
|
||||||
|
insVlaue = 5;
|
||||||
|
} else if (value === "L") {
|
||||||
|
insVlaue = 6;
|
||||||
|
} else {
|
||||||
|
this.$refs[refName].checkboxList = value.split(",");
|
||||||
|
insVlaue = 7;
|
||||||
|
}
|
||||||
|
} else if (name == "week") {
|
||||||
|
if (value === "*") {
|
||||||
|
insVlaue = 1;
|
||||||
|
} else if (value == "?") {
|
||||||
|
insVlaue = 2;
|
||||||
|
} else if (value.indexOf("-") > -1) {
|
||||||
|
let indexArr = value.split("-");
|
||||||
|
isNaN(indexArr[0])
|
||||||
|
? (this.$refs[refName].cycle01 = 0)
|
||||||
|
: (this.$refs[refName].cycle01 = indexArr[0]);
|
||||||
|
this.$refs[refName].cycle02 = indexArr[1];
|
||||||
|
insVlaue = 3;
|
||||||
|
} else if (value.indexOf("#") > -1) {
|
||||||
|
let indexArr = value.split("#");
|
||||||
|
isNaN(indexArr[0])
|
||||||
|
? (this.$refs[refName].average01 = 1)
|
||||||
|
: (this.$refs[refName].average01 = indexArr[0]);
|
||||||
|
this.$refs[refName].average02 = indexArr[1];
|
||||||
|
insVlaue = 4;
|
||||||
|
} else if (value.indexOf("L") > -1) {
|
||||||
|
let indexArr = value.split("L");
|
||||||
|
isNaN(indexArr[0])
|
||||||
|
? (this.$refs[refName].weekday = 1)
|
||||||
|
: (this.$refs[refName].weekday = indexArr[0]);
|
||||||
|
insVlaue = 5;
|
||||||
|
} else {
|
||||||
|
this.$refs[refName].checkboxList = value.split(",");
|
||||||
|
insVlaue = 7;
|
||||||
|
}
|
||||||
|
} else if (name == "year") {
|
||||||
|
if (value == "") {
|
||||||
|
insVlaue = 1;
|
||||||
|
} else if (value == "*") {
|
||||||
|
insVlaue = 2;
|
||||||
|
} else if (value.indexOf("-") > -1) {
|
||||||
|
insVlaue = 3;
|
||||||
|
} else if (value.indexOf("/") > -1) {
|
||||||
|
insVlaue = 4;
|
||||||
|
} else {
|
||||||
|
this.$refs[refName].checkboxList = value.split(",");
|
||||||
|
insVlaue = 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.$refs[refName].radioValue = insVlaue;
|
||||||
|
},
|
||||||
|
// 表单选项的子组件校验数字格式(通过-props传递)
|
||||||
|
checkNumber(value, minLimit, maxLimit) {
|
||||||
|
//检查必须为整数
|
||||||
|
value = Math.floor(value);
|
||||||
|
if (value < minLimit) {
|
||||||
|
value = minLimit;
|
||||||
|
} else if (value > maxLimit) {
|
||||||
|
value = maxLimit;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
// 隐藏弹窗
|
||||||
|
hidePopup() {
|
||||||
|
this.$emit("hide");
|
||||||
|
},
|
||||||
|
// 填充表达式
|
||||||
|
submitFill() {
|
||||||
|
this.$emit("fill", this.contabValueString);
|
||||||
|
this.hidePopup();
|
||||||
|
},
|
||||||
|
clearCron() {
|
||||||
|
// 还原选择项
|
||||||
|
("准备还原");
|
||||||
|
this.contabValueObj = {
|
||||||
|
second: "*",
|
||||||
|
min: "*",
|
||||||
|
hour: "*",
|
||||||
|
day: "*",
|
||||||
|
mouth: "*",
|
||||||
|
week: "?",
|
||||||
|
year: "",
|
||||||
|
};
|
||||||
|
for (let j in this.contabValueObj) {
|
||||||
|
this.changeRadio(j, this.contabValueObj[j]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
contabValueString: function() {
|
||||||
|
let obj = this.contabValueObj;
|
||||||
|
let str =
|
||||||
|
obj.second +
|
||||||
|
" " +
|
||||||
|
obj.min +
|
||||||
|
" " +
|
||||||
|
obj.hour +
|
||||||
|
" " +
|
||||||
|
obj.day +
|
||||||
|
" " +
|
||||||
|
obj.mouth +
|
||||||
|
" " +
|
||||||
|
obj.week +
|
||||||
|
(obj.year == "" ? "" : " " + obj.year);
|
||||||
|
return str;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
CrontabSecond,
|
||||||
|
CrontabMin,
|
||||||
|
CrontabHour,
|
||||||
|
CrontabDay,
|
||||||
|
CrontabMouth,
|
||||||
|
CrontabWeek,
|
||||||
|
CrontabYear,
|
||||||
|
CrontabResult,
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
expression: "resolveExp",
|
||||||
|
hideComponent(value) {
|
||||||
|
// 隐藏部分组件
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted: function() {
|
||||||
|
this.resolveExp();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.pop_btn {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.popup-main {
|
||||||
|
position: relative;
|
||||||
|
margin: 10px auto;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.popup-title {
|
||||||
|
overflow: hidden;
|
||||||
|
line-height: 34px;
|
||||||
|
padding-top: 6px;
|
||||||
|
background: #f2f2f2;
|
||||||
|
}
|
||||||
|
.popup-result-container {
|
||||||
|
box-sizing: border-box;
|
||||||
|
line-height: 24px;
|
||||||
|
margin: 25px auto;
|
||||||
|
padding: 15px 10px 10px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.popup-result-container .title {
|
||||||
|
position: absolute;
|
||||||
|
top: -28px;
|
||||||
|
left: 50%;
|
||||||
|
width: 140px;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-left: -70px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 30px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.popup-result-container table {
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.popup-result-container table span {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
font-family: arial;
|
||||||
|
line-height: 30px;
|
||||||
|
height: 30px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,179 @@
|
||||||
|
<template>
|
||||||
|
<el-form size="small">
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="1">
|
||||||
|
日,允许的通配符[, - * / L M]
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="2">
|
||||||
|
不指定
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="3">
|
||||||
|
周期从
|
||||||
|
<el-input-number v-model='cycle01' :min="0" :max="31" /> -
|
||||||
|
<el-input-number v-model='cycle02' :min="0" :max="31" /> 日
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="4">
|
||||||
|
从
|
||||||
|
<el-input-number v-model='average01' :min="0" :max="31" /> 号开始,每
|
||||||
|
<el-input-number v-model='average02' :min="0" :max="31" /> 日执行一次
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="5">
|
||||||
|
每月
|
||||||
|
<el-input-number v-model='workday' :min="0" :max="31" /> 号最近的那个工作日
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="6">
|
||||||
|
本月最后一天
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="7">
|
||||||
|
指定
|
||||||
|
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||||
|
<el-option v-for="item in 31" :key="item" :value="item">{{item}}</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
radioValue: 1,
|
||||||
|
workday: 1,
|
||||||
|
cycle01: 1,
|
||||||
|
cycle02: 2,
|
||||||
|
average01: 1,
|
||||||
|
average02: 1,
|
||||||
|
checkboxList: [],
|
||||||
|
checkNum: this.$options.propsData.check
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: 'CrontabDay',
|
||||||
|
props: ['check', 'cron'],
|
||||||
|
methods: {
|
||||||
|
// 单选按钮值变化时
|
||||||
|
radioChange() {
|
||||||
|
('day rachange');
|
||||||
|
if (this.radioValue === 1) {
|
||||||
|
this.$emit('update', 'day', '*', 'day');
|
||||||
|
this.$emit('update', 'week', '?', 'day');
|
||||||
|
this.$emit('update', 'mouth', '*', 'day');
|
||||||
|
} else {
|
||||||
|
if (this.cron.hour === '*') {
|
||||||
|
this.$emit('update', 'hour', '0', 'day');
|
||||||
|
}
|
||||||
|
if (this.cron.min === '*') {
|
||||||
|
this.$emit('update', 'min', '0', 'day');
|
||||||
|
}
|
||||||
|
if (this.cron.second === '*') {
|
||||||
|
this.$emit('update', 'second', '0', 'day');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (this.radioValue) {
|
||||||
|
case 2:
|
||||||
|
this.$emit('update', 'day', '?');
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
this.$emit('update', 'day', this.cycle01 + '-' + this.cycle02);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
this.$emit('update', 'day', this.average01 + '/' + this.average02);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
this.$emit('update', 'day', this.workday + 'W');
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
this.$emit('update', 'day', 'L');
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
this.$emit('update', 'day', this.checkboxString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
('day rachange end');
|
||||||
|
},
|
||||||
|
// 周期两个值变化时
|
||||||
|
cycleChange() {
|
||||||
|
if (this.radioValue == '3') {
|
||||||
|
this.$emit('update', 'day', this.cycleTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 平均两个值变化时
|
||||||
|
averageChange() {
|
||||||
|
if (this.radioValue == '4') {
|
||||||
|
this.$emit('update', 'day', this.averageTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 最近工作日值变化时
|
||||||
|
workdayChange() {
|
||||||
|
if (this.radioValue == '5') {
|
||||||
|
this.$emit('update', 'day', this.workday + 'W');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// checkbox值变化时
|
||||||
|
checkboxChange() {
|
||||||
|
if (this.radioValue == '7') {
|
||||||
|
this.$emit('update', 'day', this.checkboxString);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 父组件传递的week发生变化触发
|
||||||
|
weekChange() {
|
||||||
|
//判断week值与day不能同时为“?”
|
||||||
|
if (this.cron.week == '?' && this.radioValue == '2') {
|
||||||
|
this.radioValue = '1';
|
||||||
|
} else if (this.cron.week !== '?' && this.radioValue != '2') {
|
||||||
|
this.radioValue = '2';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
"radioValue": "radioChange",
|
||||||
|
'cycleTotal': 'cycleChange',
|
||||||
|
'averageTotal': 'averageChange',
|
||||||
|
'workdayCheck': 'workdayChange',
|
||||||
|
'checkboxString': 'checkboxChange',
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 计算两个周期值
|
||||||
|
cycleTotal: function () {
|
||||||
|
this.cycle01 = this.checkNum(this.cycle01, 1, 31)
|
||||||
|
this.cycle02 = this.checkNum(this.cycle02, 1, 31)
|
||||||
|
return this.cycle01 + '-' + this.cycle02;
|
||||||
|
},
|
||||||
|
// 计算平均用到的值
|
||||||
|
averageTotal: function () {
|
||||||
|
this.average01 = this.checkNum(this.average01, 1, 31)
|
||||||
|
this.average02 = this.checkNum(this.average02, 1, 31)
|
||||||
|
return this.average01 + '/' + this.average02;
|
||||||
|
},
|
||||||
|
// 计算工作日格式
|
||||||
|
workdayCheck: function () {
|
||||||
|
this.workday = this.checkNum(this.workday, 1, 31)
|
||||||
|
return this.workday;
|
||||||
|
},
|
||||||
|
// 计算勾选的checkbox值合集
|
||||||
|
checkboxString: function () {
|
||||||
|
let str = this.checkboxList.join();
|
||||||
|
return str == '' ? '*' : str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,122 @@
|
||||||
|
<template>
|
||||||
|
<el-form size="small">
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="1">
|
||||||
|
小时,允许的通配符[, - * /]
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="2">
|
||||||
|
周期从
|
||||||
|
<el-input-number v-model='cycle01' :min="0" :max="60" /> -
|
||||||
|
<el-input-number v-model='cycle02' :min="0" :max="60" /> 小时
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="3">
|
||||||
|
从
|
||||||
|
<el-input-number v-model='average01' :min="0" :max="60" /> 小时开始,每
|
||||||
|
<el-input-number v-model='average02' :min="0" :max="60" /> 小时执行一次
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="4">
|
||||||
|
指定
|
||||||
|
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||||
|
<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
radioValue: 1,
|
||||||
|
cycle01: 0,
|
||||||
|
cycle02: 1,
|
||||||
|
average01: 0,
|
||||||
|
average02: 1,
|
||||||
|
checkboxList: [],
|
||||||
|
checkNum: this.$options.propsData.check
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: 'CrontabHour',
|
||||||
|
props: ['check', 'cron'],
|
||||||
|
methods: {
|
||||||
|
// 单选按钮值变化时
|
||||||
|
radioChange() {
|
||||||
|
if (this.radioValue === 1) {
|
||||||
|
this.$emit('update', 'hour', '*', 'hour');
|
||||||
|
this.$emit('update', 'day', '*', 'hour');
|
||||||
|
} else {
|
||||||
|
if (this.cron.min === '*') {
|
||||||
|
this.$emit('update', 'min', '0', 'hour');
|
||||||
|
}
|
||||||
|
if (this.cron.second === '*') {
|
||||||
|
this.$emit('update', 'second', '0', 'hour');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (this.radioValue) {
|
||||||
|
case 2:
|
||||||
|
this.$emit('update', 'hour', this.cycle01 + '-' + this.cycle02);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
this.$emit('update', 'hour', this.average01 + '/' + this.average02);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
this.$emit('update', 'hour', this.checkboxString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 周期两个值变化时
|
||||||
|
cycleChange() {
|
||||||
|
if (this.radioValue == '2') {
|
||||||
|
this.$emit('update', 'hour', this.cycleTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 平均两个值变化时
|
||||||
|
averageChange() {
|
||||||
|
if (this.radioValue == '3') {
|
||||||
|
this.$emit('update', 'hour', this.averageTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// checkbox值变化时
|
||||||
|
checkboxChange() {
|
||||||
|
if (this.radioValue == '4') {
|
||||||
|
this.$emit('update', 'hour', this.checkboxString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
"radioValue": "radioChange",
|
||||||
|
'cycleTotal': 'cycleChange',
|
||||||
|
'averageTotal': 'averageChange',
|
||||||
|
'checkboxString': 'checkboxChange'
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 计算两个周期值
|
||||||
|
cycleTotal: function () {
|
||||||
|
this.cycle01 = this.checkNum(this.cycle01, 0, 23)
|
||||||
|
this.cycle02 = this.checkNum(this.cycle02, 0, 23)
|
||||||
|
return this.cycle01 + '-' + this.cycle02;
|
||||||
|
},
|
||||||
|
// 计算平均用到的值
|
||||||
|
averageTotal: function () {
|
||||||
|
this.average01 = this.checkNum(this.average01, 0, 23)
|
||||||
|
this.average02 = this.checkNum(this.average02, 1, 23)
|
||||||
|
return this.average01 + '/' + this.average02;
|
||||||
|
},
|
||||||
|
// 计算勾选的checkbox值合集
|
||||||
|
checkboxString: function () {
|
||||||
|
let str = this.checkboxList.join();
|
||||||
|
return str == '' ? '*' : str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,120 @@
|
||||||
|
<template>
|
||||||
|
<el-form size="small">
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="1">
|
||||||
|
分钟,允许的通配符[, - * /]
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="2">
|
||||||
|
周期从
|
||||||
|
<el-input-number v-model='cycle01' :min="0" :max="60" /> -
|
||||||
|
<el-input-number v-model='cycle02' :min="0" :max="60" /> 分钟
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="3">
|
||||||
|
从
|
||||||
|
<el-input-number v-model='average01' :min="0" :max="60" /> 分钟开始,每
|
||||||
|
<el-input-number v-model='average02' :min="0" :max="60" /> 分钟执行一次
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="4">
|
||||||
|
指定
|
||||||
|
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||||
|
<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
radioValue: 1,
|
||||||
|
cycle01: 1,
|
||||||
|
cycle02: 2,
|
||||||
|
average01: 0,
|
||||||
|
average02: 1,
|
||||||
|
checkboxList: [],
|
||||||
|
checkNum: this.$options.propsData.check
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: 'CrontabMin',
|
||||||
|
props: ['check', 'cron'],
|
||||||
|
methods: {
|
||||||
|
// 单选按钮值变化时
|
||||||
|
radioChange() {
|
||||||
|
if (this.radioValue !== 1 && this.cron.second === '*') {
|
||||||
|
this.$emit('update', 'second', '0', 'min');
|
||||||
|
}
|
||||||
|
switch (this.radioValue) {
|
||||||
|
case 1:
|
||||||
|
this.$emit('update', 'min', '*', 'min');
|
||||||
|
this.$emit('update', 'hour', '*', 'min');
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this.$emit('update', 'min', this.cycle01 + '-' + this.cycle02, 'min');
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
this.$emit('update', 'min', this.average01 + '/' + this.average02, 'min');
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
this.$emit('update', 'min', this.checkboxString, 'min');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 周期两个值变化时
|
||||||
|
cycleChange() {
|
||||||
|
if (this.radioValue == '2') {
|
||||||
|
this.$emit('update', 'min', this.cycleTotal, 'min');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 平均两个值变化时
|
||||||
|
averageChange() {
|
||||||
|
if (this.radioValue == '3') {
|
||||||
|
this.$emit('update', 'min', this.averageTotal, 'min');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// checkbox值变化时
|
||||||
|
checkboxChange() {
|
||||||
|
if (this.radioValue == '4') {
|
||||||
|
this.$emit('update', 'min', this.checkboxString, 'min');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
"radioValue": "radioChange",
|
||||||
|
'cycleTotal': 'cycleChange',
|
||||||
|
'averageTotal': 'averageChange',
|
||||||
|
'checkboxString': 'checkboxChange',
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 计算两个周期值
|
||||||
|
cycleTotal: function () {
|
||||||
|
this.cycle01 = this.checkNum(this.cycle01, 0, 59)
|
||||||
|
this.cycle02 = this.checkNum(this.cycle02, 0, 59)
|
||||||
|
return this.cycle01 + '-' + this.cycle02;
|
||||||
|
},
|
||||||
|
// 计算平均用到的值
|
||||||
|
averageTotal: function () {
|
||||||
|
this.average01 = this.checkNum(this.average01, 0, 59)
|
||||||
|
this.average02 = this.checkNum(this.average02, 1, 59)
|
||||||
|
return this.average01 + '/' + this.average02;
|
||||||
|
},
|
||||||
|
// 计算勾选的checkbox值合集
|
||||||
|
checkboxString: function () {
|
||||||
|
let str = this.checkboxList.join();
|
||||||
|
return str == '' ? '*' : str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,128 @@
|
||||||
|
<template>
|
||||||
|
<el-form size='small'>
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="1">
|
||||||
|
月,允许的通配符[, - * /]
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="2">
|
||||||
|
周期从
|
||||||
|
<el-input-number v-model='cycle01' :min="1" :max="12" /> -
|
||||||
|
<el-input-number v-model='cycle02' :min="1" :max="12" /> 月
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="3">
|
||||||
|
从
|
||||||
|
<el-input-number v-model='average01' :min="1" :max="12" /> 月开始,每
|
||||||
|
<el-input-number v-model='average02' :min="1" :max="12" /> 月月执行一次
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="4">
|
||||||
|
指定
|
||||||
|
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||||
|
<el-option v-for="item in 12" :key="item" :value="item">{{item}}</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
radioValue: 1,
|
||||||
|
cycle01: 1,
|
||||||
|
cycle02: 2,
|
||||||
|
average01: 1,
|
||||||
|
average02: 1,
|
||||||
|
checkboxList: [],
|
||||||
|
checkNum: this.check
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: 'CrontabMouth',
|
||||||
|
props: ['check', 'cron'],
|
||||||
|
methods: {
|
||||||
|
// 单选按钮值变化时
|
||||||
|
radioChange() {
|
||||||
|
if (this.radioValue === 1) {
|
||||||
|
this.$emit('update', 'mouth', '*');
|
||||||
|
this.$emit('update', 'year', '*');
|
||||||
|
} else {
|
||||||
|
if (this.cron.day === '*') {
|
||||||
|
this.$emit('update', 'day', '1', 'mouth');
|
||||||
|
}
|
||||||
|
if (this.cron.hour === '*') {
|
||||||
|
this.$emit('update', 'hour', '0', 'mouth');
|
||||||
|
}
|
||||||
|
if (this.cron.min === '*') {
|
||||||
|
this.$emit('update', 'min', '0', 'mouth');
|
||||||
|
}
|
||||||
|
if (this.cron.second === '*') {
|
||||||
|
this.$emit('update', 'second', '0', 'mouth');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (this.radioValue) {
|
||||||
|
case 2:
|
||||||
|
this.$emit('update', 'mouth', this.cycle01 + '-' + this.cycle02);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
this.$emit('update', 'mouth', this.average01 + '/' + this.average02);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
this.$emit('update', 'mouth', this.checkboxString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 周期两个值变化时
|
||||||
|
cycleChange() {
|
||||||
|
if (this.radioValue == '2') {
|
||||||
|
this.$emit('update', 'mouth', this.cycleTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 平均两个值变化时
|
||||||
|
averageChange() {
|
||||||
|
if (this.radioValue == '3') {
|
||||||
|
this.$emit('update', 'mouth', this.averageTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// checkbox值变化时
|
||||||
|
checkboxChange() {
|
||||||
|
if (this.radioValue == '4') {
|
||||||
|
this.$emit('update', 'mouth', this.checkboxString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
"radioValue": "radioChange",
|
||||||
|
'cycleTotal': 'cycleChange',
|
||||||
|
'averageTotal': 'averageChange',
|
||||||
|
'checkboxString': 'checkboxChange'
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 计算两个周期值
|
||||||
|
cycleTotal: function () {
|
||||||
|
this.cycle01 = this.checkNum(this.cycle01, 1, 12)
|
||||||
|
this.cycle02 = this.checkNum(this.cycle02, 1, 12)
|
||||||
|
return this.cycle01 + '-' + this.cycle02;
|
||||||
|
},
|
||||||
|
// 计算平均用到的值
|
||||||
|
averageTotal: function () {
|
||||||
|
this.average01 = this.checkNum(this.average01, 1, 12)
|
||||||
|
this.average02 = this.checkNum(this.average02, 1, 12)
|
||||||
|
return this.average01 + '/' + this.average02;
|
||||||
|
},
|
||||||
|
// 计算勾选的checkbox值合集
|
||||||
|
checkboxString: function () {
|
||||||
|
let str = this.checkboxList.join();
|
||||||
|
return str == '' ? '*' : str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,592 @@
|
||||||
|
<template>
|
||||||
|
<div class="popup-result">
|
||||||
|
<p class="title">最近5次运行时间</p>
|
||||||
|
<ul class="popup-result-scroll">
|
||||||
|
<template>
|
||||||
|
<li v-for='item in resultList' :key="item">{{item}}</li>
|
||||||
|
</template>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'CrontabResult',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dayRule: '',
|
||||||
|
dayRuleSup: '',
|
||||||
|
dateArr: [],
|
||||||
|
resultList: [],
|
||||||
|
isShow: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'ex': 'expressionChange'
|
||||||
|
},
|
||||||
|
props: ['ex'],
|
||||||
|
mounted: function () {
|
||||||
|
// 初始化 获取一次结果
|
||||||
|
this.expressionChange();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 表达式值变化时,开始去计算结果
|
||||||
|
expressionChange() {
|
||||||
|
// 计算开始-隐藏结果
|
||||||
|
this.isShow = false;
|
||||||
|
if (!this.ex) {
|
||||||
|
this.resultList = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 获取规则数组[0秒、1分、2时、3日、4月、5星期、6年]
|
||||||
|
let ruleArr = this.$options.propsData.ex.split(' ');
|
||||||
|
// 用于记录进入循环的次数
|
||||||
|
let nums = 0;
|
||||||
|
// 用于暂时存符号时间规则结果的数组
|
||||||
|
let resultArr = [];
|
||||||
|
// 获取当前时间精确至[年、月、日、时、分、秒]
|
||||||
|
let nTime = new Date();
|
||||||
|
let nYear = nTime.getFullYear();
|
||||||
|
let nMouth = nTime.getMonth() + 1;
|
||||||
|
let nDay = nTime.getDate();
|
||||||
|
let nHour = nTime.getHours();
|
||||||
|
let nMin = nTime.getMinutes();
|
||||||
|
let nSecond = nTime.getSeconds();
|
||||||
|
// 根据规则获取到近100年可能年数组、月数组等等
|
||||||
|
this.getSecondArr(ruleArr[0]);
|
||||||
|
this.getMinArr(ruleArr[1]);
|
||||||
|
this.getHourArr(ruleArr[2]);
|
||||||
|
this.getDayArr(ruleArr[3]);
|
||||||
|
this.getMouthArr(ruleArr[4]);
|
||||||
|
this.getWeekArr(ruleArr[5]);
|
||||||
|
this.getYearArr(ruleArr[6], nYear);
|
||||||
|
// 将获取到的数组赋值-方便使用
|
||||||
|
let sDate = this.dateArr[0];
|
||||||
|
let mDate = this.dateArr[1];
|
||||||
|
let hDate = this.dateArr[2];
|
||||||
|
let DDate = this.dateArr[3];
|
||||||
|
let MDate = this.dateArr[4];
|
||||||
|
let YDate = this.dateArr[5];
|
||||||
|
// 获取当前时间在数组中的索引
|
||||||
|
let sIdx = this.getIndex(sDate, nSecond);
|
||||||
|
let mIdx = this.getIndex(mDate, nMin);
|
||||||
|
let hIdx = this.getIndex(hDate, nHour);
|
||||||
|
let DIdx = this.getIndex(DDate, nDay);
|
||||||
|
let MIdx = this.getIndex(MDate, nMouth);
|
||||||
|
let YIdx = this.getIndex(YDate, nYear);
|
||||||
|
// 重置月日时分秒的函数(后面用的比较多)
|
||||||
|
const resetSecond = function () {
|
||||||
|
sIdx = 0;
|
||||||
|
nSecond = sDate[sIdx]
|
||||||
|
}
|
||||||
|
const resetMin = function () {
|
||||||
|
mIdx = 0;
|
||||||
|
nMin = mDate[mIdx]
|
||||||
|
resetSecond();
|
||||||
|
}
|
||||||
|
const resetHour = function () {
|
||||||
|
hIdx = 0;
|
||||||
|
nHour = hDate[hIdx]
|
||||||
|
resetMin();
|
||||||
|
}
|
||||||
|
const resetDay = function () {
|
||||||
|
DIdx = 0;
|
||||||
|
nDay = DDate[DIdx]
|
||||||
|
resetHour();
|
||||||
|
}
|
||||||
|
const resetMouth = function () {
|
||||||
|
MIdx = 0;
|
||||||
|
nMouth = MDate[MIdx]
|
||||||
|
resetDay();
|
||||||
|
}
|
||||||
|
// 如果当前年份不为数组中当前值
|
||||||
|
if (nYear !== YDate[YIdx]) {
|
||||||
|
resetMouth();
|
||||||
|
}
|
||||||
|
// 如果当前月份不为数组中当前值
|
||||||
|
if (nMouth !== MDate[MIdx]) {
|
||||||
|
resetDay();
|
||||||
|
}
|
||||||
|
// 如果当前“日”不为数组中当前值
|
||||||
|
if (nDay !== DDate[DIdx]) {
|
||||||
|
resetHour();
|
||||||
|
}
|
||||||
|
// 如果当前“时”不为数组中当前值
|
||||||
|
if (nHour !== hDate[hIdx]) {
|
||||||
|
resetMin();
|
||||||
|
}
|
||||||
|
// 如果当前“分”不为数组中当前值
|
||||||
|
if (nMin !== mDate[mIdx]) {
|
||||||
|
resetSecond();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 循环年份数组
|
||||||
|
goYear: for (let Yi = YIdx; Yi < YDate.length; Yi++) {
|
||||||
|
let YY = YDate[Yi];
|
||||||
|
// 如果到达最大值时
|
||||||
|
if (nMouth > MDate[MDate.length - 1]) {
|
||||||
|
resetMouth();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 循环月份数组
|
||||||
|
goMouth: for (let Mi = MIdx; Mi < MDate.length; Mi++) {
|
||||||
|
// 赋值、方便后面运算
|
||||||
|
let MM = MDate[Mi];
|
||||||
|
MM = MM < 10 ? '0' + MM : MM;
|
||||||
|
// 如果到达最大值时
|
||||||
|
if (nDay > DDate[DDate.length - 1]) {
|
||||||
|
resetDay();
|
||||||
|
if (Mi == MDate.length - 1) {
|
||||||
|
resetMouth();
|
||||||
|
continue goYear;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 循环日期数组
|
||||||
|
goDay: for (let Di = DIdx; Di < DDate.length; Di++) {
|
||||||
|
// 赋值、方便后面运算
|
||||||
|
let DD = DDate[Di];
|
||||||
|
let thisDD = DD < 10 ? '0' + DD : DD;
|
||||||
|
|
||||||
|
// 如果到达最大值时
|
||||||
|
if (nHour > hDate[hDate.length - 1]) {
|
||||||
|
resetHour();
|
||||||
|
if (Di == DDate.length - 1) {
|
||||||
|
resetDay();
|
||||||
|
if (Mi == MDate.length - 1) {
|
||||||
|
resetMouth();
|
||||||
|
continue goYear;
|
||||||
|
}
|
||||||
|
continue goMouth;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断日期的合法性,不合法的话也是跳出当前循环
|
||||||
|
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true && this.dayRule !== 'workDay' && this.dayRule !== 'lastWeek' && this.dayRule !== 'lastDay') {
|
||||||
|
resetDay();
|
||||||
|
continue goMouth;
|
||||||
|
}
|
||||||
|
// 如果日期规则中有值时
|
||||||
|
if (this.dayRule == 'lastDay') {
|
||||||
|
//如果不是合法日期则需要将前将日期调到合法日期即月末最后一天
|
||||||
|
|
||||||
|
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
|
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
|
DD--;
|
||||||
|
|
||||||
|
thisDD = DD < 10 ? '0' + DD : DD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (this.dayRule == 'workDay') {
|
||||||
|
//校验并调整如果是2月30号这种日期传进来时需调整至正常月底
|
||||||
|
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
|
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
|
DD--;
|
||||||
|
thisDD = DD < 10 ? '0' + DD : DD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获取达到条件的日期是星期X
|
||||||
|
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week');
|
||||||
|
// 当星期日时
|
||||||
|
if (thisWeek == 0) {
|
||||||
|
//先找下一个日,并判断是否为月底
|
||||||
|
DD++;
|
||||||
|
thisDD = DD < 10 ? '0' + DD : DD;
|
||||||
|
//判断下一日已经不是合法日期
|
||||||
|
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
|
DD -= 3;
|
||||||
|
}
|
||||||
|
} else if (thisWeek == 6) {
|
||||||
|
//当星期6时只需判断不是1号就可进行操作
|
||||||
|
if (this.dayRuleSup !== 1) {
|
||||||
|
DD--;
|
||||||
|
} else {
|
||||||
|
DD += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (this.dayRule == 'weekDay') {
|
||||||
|
//如果指定了是星期几
|
||||||
|
//获取当前日期是属于星期几
|
||||||
|
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week');
|
||||||
|
//校验当前星期是否在星期池(dayRuleSup)中
|
||||||
|
if (Array.indexOf(this.dayRuleSup, thisWeek) < 0) {
|
||||||
|
// 如果到达最大值时
|
||||||
|
if (Di == DDate.length - 1) {
|
||||||
|
resetDay();
|
||||||
|
if (Mi == MDate.length - 1) {
|
||||||
|
resetMouth();
|
||||||
|
continue goYear;
|
||||||
|
}
|
||||||
|
continue goMouth;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (this.dayRule == 'assWeek') {
|
||||||
|
//如果指定了是第几周的星期几
|
||||||
|
//获取每月1号是属于星期几
|
||||||
|
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week');
|
||||||
|
if (this.dayRuleSup[1] >= thisWeek) {
|
||||||
|
DD = (this.dayRuleSup[0] - 1) * 7 + this.dayRuleSup[1] - thisWeek + 1;
|
||||||
|
} else {
|
||||||
|
DD = this.dayRuleSup[0] * 7 + this.dayRuleSup[1] - thisWeek + 1;
|
||||||
|
}
|
||||||
|
} else if (this.dayRule == 'lastWeek') {
|
||||||
|
//如果指定了每月最后一个星期几
|
||||||
|
//校验并调整如果是2月30号这种日期传进来时需调整至正常月底
|
||||||
|
if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
|
while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
|
||||||
|
DD--;
|
||||||
|
thisDD = DD < 10 ? '0' + DD : DD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//获取月末最后一天是星期几
|
||||||
|
let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week');
|
||||||
|
//找到要求中最近的那个星期几
|
||||||
|
if (this.dayRuleSup < thisWeek) {
|
||||||
|
DD -= thisWeek - this.dayRuleSup;
|
||||||
|
} else if (this.dayRuleSup > thisWeek) {
|
||||||
|
DD -= 7 - (this.dayRuleSup - thisWeek)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 判断时间值是否小于10置换成“05”这种格式
|
||||||
|
DD = DD < 10 ? '0' + DD : DD;
|
||||||
|
|
||||||
|
// 循环“时”数组
|
||||||
|
goHour: for (let hi = hIdx; hi < hDate.length; hi++) {
|
||||||
|
let hh = hDate[hi] < 10 ? '0' + hDate[hi] : hDate[hi]
|
||||||
|
|
||||||
|
// 如果到达最大值时
|
||||||
|
if (nMin > mDate[mDate.length - 1]) {
|
||||||
|
resetMin();
|
||||||
|
if (hi == hDate.length - 1) {
|
||||||
|
resetHour();
|
||||||
|
if (Di == DDate.length - 1) {
|
||||||
|
resetDay();
|
||||||
|
if (Mi == MDate.length - 1) {
|
||||||
|
resetMouth();
|
||||||
|
continue goYear;
|
||||||
|
}
|
||||||
|
continue goMouth;
|
||||||
|
}
|
||||||
|
continue goDay;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 循环"分"数组
|
||||||
|
goMin: for (let mi = mIdx; mi < mDate.length; mi++) {
|
||||||
|
let mm = mDate[mi] < 10 ? '0' + mDate[mi] : mDate[mi];
|
||||||
|
|
||||||
|
// 如果到达最大值时
|
||||||
|
if (nSecond > sDate[sDate.length - 1]) {
|
||||||
|
resetSecond();
|
||||||
|
if (mi == mDate.length - 1) {
|
||||||
|
resetMin();
|
||||||
|
if (hi == hDate.length - 1) {
|
||||||
|
resetHour();
|
||||||
|
if (Di == DDate.length - 1) {
|
||||||
|
resetDay();
|
||||||
|
if (Mi == MDate.length - 1) {
|
||||||
|
resetMouth();
|
||||||
|
continue goYear;
|
||||||
|
}
|
||||||
|
continue goMouth;
|
||||||
|
}
|
||||||
|
continue goDay;
|
||||||
|
}
|
||||||
|
continue goHour;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 循环"秒"数组
|
||||||
|
goSecond: for (let si = sIdx; si <= sDate.length - 1; si++) {
|
||||||
|
let ss = sDate[si] < 10 ? '0' + sDate[si] : sDate[si];
|
||||||
|
// 添加当前时间(时间合法性在日期循环时已经判断)
|
||||||
|
if (MM !== '00' && DD !== '00') {
|
||||||
|
resultArr.push(YY + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss)
|
||||||
|
nums++;
|
||||||
|
}
|
||||||
|
//如果条数满了就退出循环
|
||||||
|
if (nums == 5) break goYear;
|
||||||
|
//如果到达最大值时
|
||||||
|
if (si == sDate.length - 1) {
|
||||||
|
resetSecond();
|
||||||
|
if (mi == mDate.length - 1) {
|
||||||
|
resetMin();
|
||||||
|
if (hi == hDate.length - 1) {
|
||||||
|
resetHour();
|
||||||
|
if (Di == DDate.length - 1) {
|
||||||
|
resetDay();
|
||||||
|
if (Mi == MDate.length - 1) {
|
||||||
|
resetMouth();
|
||||||
|
continue goYear;
|
||||||
|
}
|
||||||
|
continue goMouth;
|
||||||
|
}
|
||||||
|
continue goDay;
|
||||||
|
}
|
||||||
|
continue goHour;
|
||||||
|
}
|
||||||
|
continue goMin;
|
||||||
|
}
|
||||||
|
} //goSecond
|
||||||
|
} //goMin
|
||||||
|
}//goHour
|
||||||
|
}//goDay
|
||||||
|
}//goMouth
|
||||||
|
}
|
||||||
|
// 判断100年内的结果条数
|
||||||
|
if (resultArr.length == 0) {
|
||||||
|
this.resultList = ['没有达到条件的结果!'];
|
||||||
|
} else {
|
||||||
|
this.resultList = resultArr;
|
||||||
|
if (resultArr.length !== 5) {
|
||||||
|
this.resultList.push('最近100年内只有上面' + resultArr.length + '条结果!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$emit("resultListChange", this.resultList);
|
||||||
|
// 计算完成-显示结果
|
||||||
|
this.isShow = true;
|
||||||
|
|
||||||
|
},
|
||||||
|
//用于计算某位数字在数组中的索引
|
||||||
|
getIndex(arr, value) {
|
||||||
|
if (value <= arr[0] || value > arr[arr.length - 1]) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
for (let i = 0; i < arr.length - 1; i++) {
|
||||||
|
if (value > arr[i] && value <= arr[i + 1]) {
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取"年"数组
|
||||||
|
getYearArr(rule, year) {
|
||||||
|
this.dateArr[5] = this.getOrderArr(year, year + 100);
|
||||||
|
if (rule !== undefined) {
|
||||||
|
if (rule.indexOf('-') >= 0) {
|
||||||
|
this.dateArr[5] = this.getCycleArr(rule, year + 100, false)
|
||||||
|
} else if (rule.indexOf('/') >= 0) {
|
||||||
|
this.dateArr[5] = this.getAverageArr(rule, year + 100)
|
||||||
|
} else if (rule !== '*') {
|
||||||
|
this.dateArr[5] = this.getAssignArr(rule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取"月"数组
|
||||||
|
getMouthArr(rule) {
|
||||||
|
this.dateArr[4] = this.getOrderArr(1, 12);
|
||||||
|
if (rule.indexOf('-') >= 0) {
|
||||||
|
this.dateArr[4] = this.getCycleArr(rule, 12, false)
|
||||||
|
} else if (rule.indexOf('/') >= 0) {
|
||||||
|
this.dateArr[4] = this.getAverageArr(rule, 12)
|
||||||
|
} else if (rule !== '*') {
|
||||||
|
this.dateArr[4] = this.getAssignArr(rule)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取"日"数组-主要为日期规则
|
||||||
|
getWeekArr(rule) {
|
||||||
|
//只有当日期规则的两个值均为“”时则表达日期是有选项的
|
||||||
|
if (this.dayRule == '' && this.dayRuleSup == '') {
|
||||||
|
if (rule.indexOf('-') >= 0) {
|
||||||
|
this.dayRule = 'weekDay';
|
||||||
|
this.dayRuleSup = this.getCycleArr(rule, 7, false)
|
||||||
|
} else if (rule.indexOf('#') >= 0) {
|
||||||
|
this.dayRule = 'assWeek';
|
||||||
|
let matchRule = rule.match(/[0-9]{1}/g);
|
||||||
|
this.dayRuleSup = [Number(matchRule[0]), Number(matchRule[1])];
|
||||||
|
this.dateArr[3] = [1];
|
||||||
|
if (this.dayRuleSup[1] == 7) {
|
||||||
|
this.dayRuleSup[1] = 0;
|
||||||
|
}
|
||||||
|
} else if (rule.indexOf('L') >= 0) {
|
||||||
|
this.dayRule = 'lastWeek';
|
||||||
|
this.dayRuleSup = Number(rule.match(/[0-9]{1,2}/g)[0]);
|
||||||
|
this.dateArr[3] = [31];
|
||||||
|
if (this.dayRuleSup == 7) {
|
||||||
|
this.dayRuleSup = 0;
|
||||||
|
}
|
||||||
|
} else if (rule !== '*' && rule !== '?') {
|
||||||
|
this.dayRule = 'weekDay';
|
||||||
|
this.dayRuleSup = this.getAssignArr(rule)
|
||||||
|
}
|
||||||
|
//如果weekDay时将7调整为0【week值0即是星期日】
|
||||||
|
if (this.dayRule == 'weekDay') {
|
||||||
|
for (let i = 0; i < this.dayRuleSup.length; i++) {
|
||||||
|
if (this.dayRuleSup[i] == 7) {
|
||||||
|
this.dayRuleSup[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取"日"数组-少量为日期规则
|
||||||
|
getDayArr(rule) {
|
||||||
|
this.dateArr[3] = this.getOrderArr(1, 31);
|
||||||
|
this.dayRule = '';
|
||||||
|
this.dayRuleSup = '';
|
||||||
|
if (rule.indexOf('-') >= 0) {
|
||||||
|
this.dateArr[3] = this.getCycleArr(rule, 31, false)
|
||||||
|
this.dayRuleSup = 'null';
|
||||||
|
} else if (rule.indexOf('/') >= 0) {
|
||||||
|
this.dateArr[3] = this.getAverageArr(rule, 31)
|
||||||
|
this.dayRuleSup = 'null';
|
||||||
|
} else if (rule.indexOf('W') >= 0) {
|
||||||
|
this.dayRule = 'workDay';
|
||||||
|
this.dayRuleSup = Number(rule.match(/[0-9]{1,2}/g)[0]);
|
||||||
|
this.dateArr[3] = [this.dayRuleSup];
|
||||||
|
} else if (rule.indexOf('L') >= 0) {
|
||||||
|
this.dayRule = 'lastDay';
|
||||||
|
this.dayRuleSup = 'null';
|
||||||
|
this.dateArr[3] = [31];
|
||||||
|
} else if (rule !== '*' && rule !== '?') {
|
||||||
|
this.dateArr[3] = this.getAssignArr(rule)
|
||||||
|
this.dayRuleSup = 'null';
|
||||||
|
} else if (rule == '*') {
|
||||||
|
this.dayRuleSup = 'null';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取"时"数组
|
||||||
|
getHourArr(rule) {
|
||||||
|
this.dateArr[2] = this.getOrderArr(0, 23);
|
||||||
|
if (rule.indexOf('-') >= 0) {
|
||||||
|
this.dateArr[2] = this.getCycleArr(rule, 24, true)
|
||||||
|
} else if (rule.indexOf('/') >= 0) {
|
||||||
|
this.dateArr[2] = this.getAverageArr(rule, 23)
|
||||||
|
} else if (rule !== '*') {
|
||||||
|
this.dateArr[2] = this.getAssignArr(rule)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取"分"数组
|
||||||
|
getMinArr(rule) {
|
||||||
|
this.dateArr[1] = this.getOrderArr(0, 59);
|
||||||
|
if (rule.indexOf('-') >= 0) {
|
||||||
|
this.dateArr[1] = this.getCycleArr(rule, 60, true)
|
||||||
|
} else if (rule.indexOf('/') >= 0) {
|
||||||
|
this.dateArr[1] = this.getAverageArr(rule, 59)
|
||||||
|
} else if (rule !== '*') {
|
||||||
|
this.dateArr[1] = this.getAssignArr(rule)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取"秒"数组
|
||||||
|
getSecondArr(rule) {
|
||||||
|
this.dateArr[0] = this.getOrderArr(0, 59);
|
||||||
|
if (rule.indexOf('-') >= 0) {
|
||||||
|
this.dateArr[0] = this.getCycleArr(rule, 60, true)
|
||||||
|
} else if (rule.indexOf('/') >= 0) {
|
||||||
|
this.dateArr[0] = this.getAverageArr(rule, 59)
|
||||||
|
} else if (rule !== '*') {
|
||||||
|
this.dateArr[0] = this.getAssignArr(rule)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 根据传进来的min-max返回一个顺序的数组
|
||||||
|
getOrderArr(min, max) {
|
||||||
|
let arr = [];
|
||||||
|
for (let i = min; i <= max; i++) {
|
||||||
|
arr.push(i);
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
},
|
||||||
|
// 根据规则中指定的零散值返回一个数组
|
||||||
|
getAssignArr(rule) {
|
||||||
|
let arr = [];
|
||||||
|
let assiginArr = rule.split(',');
|
||||||
|
for (let i = 0; i < assiginArr.length; i++) {
|
||||||
|
arr[i] = Number(assiginArr[i])
|
||||||
|
}
|
||||||
|
arr.sort(this.compare)
|
||||||
|
return arr;
|
||||||
|
},
|
||||||
|
// 根据一定算术规则计算返回一个数组
|
||||||
|
getAverageArr(rule, limit) {
|
||||||
|
let arr = [];
|
||||||
|
let agArr = rule.split('/');
|
||||||
|
let min = Number(agArr[0]);
|
||||||
|
let step = Number(agArr[1]);
|
||||||
|
while (min <= limit) {
|
||||||
|
arr.push(min);
|
||||||
|
min += step;
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
},
|
||||||
|
// 根据规则返回一个具有周期性的数组
|
||||||
|
getCycleArr(rule, limit, status) {
|
||||||
|
//status--表示是否从0开始(则从1开始)
|
||||||
|
let arr = [];
|
||||||
|
let cycleArr = rule.split('-');
|
||||||
|
let min = Number(cycleArr[0]);
|
||||||
|
let max = Number(cycleArr[1]);
|
||||||
|
if (min > max) {
|
||||||
|
max += limit;
|
||||||
|
}
|
||||||
|
for (let i = min; i <= max; i++) {
|
||||||
|
let add = 0;
|
||||||
|
if (status == false && i % limit == 0) {
|
||||||
|
add = limit;
|
||||||
|
}
|
||||||
|
arr.push(Math.round(i % limit + add))
|
||||||
|
}
|
||||||
|
arr.sort(this.compare)
|
||||||
|
return arr;
|
||||||
|
},
|
||||||
|
//比较数字大小(用于Array.sort)
|
||||||
|
compare(value1, value2) {
|
||||||
|
if (value2 - value1 > 0) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 格式化日期格式如:2017-9-19 18:04:33
|
||||||
|
formatDate(value, type) {
|
||||||
|
// 计算日期相关值
|
||||||
|
let time = typeof value == 'number' ? new Date(value) : value;
|
||||||
|
let Y = time.getFullYear();
|
||||||
|
let M = time.getMonth() + 1;
|
||||||
|
let D = time.getDate();
|
||||||
|
let h = time.getHours();
|
||||||
|
let m = time.getMinutes();
|
||||||
|
let s = time.getSeconds();
|
||||||
|
let week = time.getDay();
|
||||||
|
// 如果传递了type的话
|
||||||
|
if (type == undefined) {
|
||||||
|
return Y + '-' + (M < 10 ? '0' + M : M) + '-' + (D < 10 ? '0' + D : D) + ' ' + (h < 10 ? '0' + h : h) + ':' + (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
|
||||||
|
} else if (type == 'week') {
|
||||||
|
return week;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 检查日期是否存在
|
||||||
|
checkDate(value) {
|
||||||
|
let time = new Date(value);
|
||||||
|
let format = this.formatDate(time)
|
||||||
|
return value == format ? true : false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-result-scroll {
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 24px;
|
||||||
|
height: 10em;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-result {
|
||||||
|
box-sizing: border-box;
|
||||||
|
line-height: 24px;
|
||||||
|
margin: 25px auto;
|
||||||
|
padding: 15px 10px 10px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,133 @@
|
||||||
|
<template>
|
||||||
|
<el-form size="small">
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="1">
|
||||||
|
秒,允许的通配符[, - * /]
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="2">
|
||||||
|
周期从
|
||||||
|
<el-input-number v-model='cycle01' :min="0" :max="60" /> -
|
||||||
|
<el-input-number v-model='cycle02' :min="0" :max="60" /> 秒
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="3">
|
||||||
|
从
|
||||||
|
<el-input-number v-model='average01' :min="0" :max="60" /> 秒开始,每
|
||||||
|
<el-input-number v-model='average02' :min="0" :max="60" /> 秒执行一次
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="4">
|
||||||
|
指定
|
||||||
|
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||||
|
<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
radioValue: 1,
|
||||||
|
cycle01: 1,
|
||||||
|
cycle02: 2,
|
||||||
|
average01: 0,
|
||||||
|
average02: 1,
|
||||||
|
checkboxList: [],
|
||||||
|
checkNum: this.$options.propsData.check
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: 'CrontabSecond',
|
||||||
|
props: ['check', 'radioParent'],
|
||||||
|
methods: {
|
||||||
|
// 单选按钮值变化时
|
||||||
|
radioChange() {
|
||||||
|
switch (this.radioValue) {
|
||||||
|
case 1:
|
||||||
|
this.$emit('update', 'second', '*', 'second');
|
||||||
|
this.$emit('update', 'min', '*', 'second');
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this.$emit('update', 'second', this.cycle01 + '-' + this.cycle02);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
this.$emit('update', 'second', this.average01 + '/' + this.average02);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
this.$emit('update', 'second', this.checkboxString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 周期两个值变化时
|
||||||
|
cycleChange() {
|
||||||
|
if (this.radioValue == '2') {
|
||||||
|
this.$emit('update', 'second', this.cycleTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 平均两个值变化时
|
||||||
|
averageChange() {
|
||||||
|
if (this.radioValue == '3') {
|
||||||
|
this.$emit('update', 'second', this.averageTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// checkbox值变化时
|
||||||
|
checkboxChange() {
|
||||||
|
if (this.radioValue == '4') {
|
||||||
|
this.$emit('update', 'second', this.checkboxString);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
othChange() {
|
||||||
|
//反解析
|
||||||
|
let ins = this.cron.second
|
||||||
|
// ('反解析 second', ins);
|
||||||
|
if (ins === '*') {
|
||||||
|
this.radioValue = 1;
|
||||||
|
} else if (ins.indexOf('-') > -1) {
|
||||||
|
this.radioValue = 2
|
||||||
|
} else if (ins.indexOf('/') > -1) {
|
||||||
|
this.radioValue = 3
|
||||||
|
} else {
|
||||||
|
this.radioValue = 4
|
||||||
|
this.checkboxList = ins.split(',')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
"radioValue": "radioChange",
|
||||||
|
'cycleTotal': 'cycleChange',
|
||||||
|
'averageTotal': 'averageChange',
|
||||||
|
'checkboxString': 'checkboxChange',
|
||||||
|
radioParent() {
|
||||||
|
this.radioValue = this.radioParent
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 计算两个周期值
|
||||||
|
cycleTotal: function () {
|
||||||
|
this.cycle01 = this.checkNum(this.cycle01, 0, 59);
|
||||||
|
this.cycle02 = this.checkNum(this.cycle02, 0, 59);
|
||||||
|
return this.cycle01 + '-' + this.cycle02;
|
||||||
|
},
|
||||||
|
// 计算平均用到的值
|
||||||
|
averageTotal: function () {
|
||||||
|
this.average01 = this.checkNum(this.average01, 0, 59)
|
||||||
|
this.average02 = this.checkNum(this.average02, 1, 59)
|
||||||
|
return this.average01 + '/' + this.average02;
|
||||||
|
},
|
||||||
|
// 计算勾选的checkbox值合集
|
||||||
|
checkboxString: function () {
|
||||||
|
let str = this.checkboxList.join();
|
||||||
|
return str == '' ? '*' : str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,167 @@
|
||||||
|
<template>
|
||||||
|
<el-form size='small'>
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="1">
|
||||||
|
周,允许的通配符[, - * / L #]
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="2">
|
||||||
|
不指定
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="3">
|
||||||
|
周期从星期
|
||||||
|
<el-input-number v-model='cycle01' :min="1" :max="7" /> -
|
||||||
|
<el-input-number v-model='cycle02' :min="1" :max="7" />
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="4">
|
||||||
|
第
|
||||||
|
<el-input-number v-model='average01' :min="1" :max="4" /> 周的星期
|
||||||
|
<el-input-number v-model='average02' :min="1" :max="7" />
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="5">
|
||||||
|
本月最后一个星期
|
||||||
|
<el-input-number v-model='weekday' :min="1" :max="7" />
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio v-model='radioValue' :label="6">
|
||||||
|
指定
|
||||||
|
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
|
||||||
|
<el-option v-for="(item,index) of weekList" :key="index" :value="index+1">{{item}}</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
radioValue: 2,
|
||||||
|
weekday: 1,
|
||||||
|
cycle01: 1,
|
||||||
|
cycle02: 2,
|
||||||
|
average01: 1,
|
||||||
|
average02: 1,
|
||||||
|
checkboxList: [],
|
||||||
|
weekList: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
|
||||||
|
checkNum: this.$options.propsData.check
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: 'CrontabWeek',
|
||||||
|
props: ['check', 'cron'],
|
||||||
|
methods: {
|
||||||
|
// 单选按钮值变化时
|
||||||
|
radioChange() {
|
||||||
|
if (this.radioValue === 1) {
|
||||||
|
this.$emit('update', 'week', '*');
|
||||||
|
this.$emit('update', 'year', '*');
|
||||||
|
} else {
|
||||||
|
if (this.cron.mouth === '*') {
|
||||||
|
this.$emit('update', 'mouth', '1', 'week');
|
||||||
|
}
|
||||||
|
if (this.cron.day === '*') {
|
||||||
|
this.$emit('update', 'day', '1', 'week');
|
||||||
|
}
|
||||||
|
if (this.cron.hour === '*') {
|
||||||
|
this.$emit('update', 'hour', '0', 'week');
|
||||||
|
}
|
||||||
|
if (this.cron.min === '*') {
|
||||||
|
this.$emit('update', 'min', '0', 'week');
|
||||||
|
}
|
||||||
|
if (this.cron.second === '*') {
|
||||||
|
this.$emit('update', 'second', '0', 'week');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (this.radioValue) {
|
||||||
|
case 2:
|
||||||
|
this.$emit('update', 'week', '?');
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
this.$emit('update', 'week', this.cycle01 + '-' + this.cycle02);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
this.$emit('update', 'week', this.average01 + '#' + this.average02);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
this.$emit('update', 'week', this.weekday + 'L');
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
this.$emit('update', 'week', this.checkboxString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 根据互斥事件,更改radio的值
|
||||||
|
|
||||||
|
// 周期两个值变化时
|
||||||
|
cycleChange() {
|
||||||
|
if (this.radioValue == '3') {
|
||||||
|
this.$emit('update', 'week', this.cycleTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 平均两个值变化时
|
||||||
|
averageChange() {
|
||||||
|
if (this.radioValue == '4') {
|
||||||
|
this.$emit('update', 'week', this.averageTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 最近工作日值变化时
|
||||||
|
weekdayChange() {
|
||||||
|
if (this.radioValue == '5') {
|
||||||
|
this.$emit('update', 'week', this.weekday + 'L');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// checkbox值变化时
|
||||||
|
checkboxChange() {
|
||||||
|
if (this.radioValue == '6') {
|
||||||
|
this.$emit('update', 'week', this.checkboxString);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
"radioValue": "radioChange",
|
||||||
|
'cycleTotal': 'cycleChange',
|
||||||
|
'averageTotal': 'averageChange',
|
||||||
|
'weekdayCheck': 'weekdayChange',
|
||||||
|
'checkboxString': 'checkboxChange',
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 计算两个周期值
|
||||||
|
cycleTotal: function () {
|
||||||
|
this.cycle01 = this.checkNum(this.cycle01, 1, 7)
|
||||||
|
this.cycle02 = this.checkNum(this.cycle02, 1, 7)
|
||||||
|
return this.cycle01 + '-' + this.cycle02;
|
||||||
|
},
|
||||||
|
// 计算平均用到的值
|
||||||
|
averageTotal: function () {
|
||||||
|
this.average01 = this.checkNum(this.average01, 1, 4)
|
||||||
|
this.average02 = this.checkNum(this.average02, 1, 7)
|
||||||
|
return this.average01 + '#' + this.average02;
|
||||||
|
},
|
||||||
|
// 最近的工作日(格式)
|
||||||
|
weekdayCheck: function () {
|
||||||
|
this.weekday = this.checkNum(this.weekday, 1, 7)
|
||||||
|
return this.weekday;
|
||||||
|
},
|
||||||
|
// 计算勾选的checkbox值合集
|
||||||
|
checkboxString: function () {
|
||||||
|
let str = this.checkboxList.join();
|
||||||
|
return str == '' ? '?' : str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,144 @@
|
||||||
|
<template>
|
||||||
|
<el-form size="small">
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio :label="1" v-model='radioValue'>
|
||||||
|
不填,允许的通配符[, - * /]
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio :label="2" v-model='radioValue'>
|
||||||
|
每年
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio :label="3" v-model='radioValue'>
|
||||||
|
周期从
|
||||||
|
<el-input-number v-model='cycle01' :min='fullYear' /> -
|
||||||
|
<el-input-number v-model='cycle02' :min='fullYear' />
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio :label="4" v-model='radioValue'>
|
||||||
|
从
|
||||||
|
<el-input-number v-model='average01' :min='fullYear' /> 年开始,每
|
||||||
|
<el-input-number v-model='average02' :min='fullYear' /> 年执行一次
|
||||||
|
</el-radio>
|
||||||
|
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-radio :label="5" v-model='radioValue'>
|
||||||
|
指定
|
||||||
|
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple>
|
||||||
|
<el-option v-for="item in 9" :key="item" :value="item - 1 + fullYear" :label="item -1 + fullYear" />
|
||||||
|
</el-select>
|
||||||
|
</el-radio>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
fullYear: 0,
|
||||||
|
radioValue: 1,
|
||||||
|
cycle01: 0,
|
||||||
|
cycle02: 0,
|
||||||
|
average01: 0,
|
||||||
|
average02: 1,
|
||||||
|
checkboxList: [],
|
||||||
|
checkNum: this.$options.propsData.check
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: 'CrontabYear',
|
||||||
|
props: ['check', 'mouth', 'cron'],
|
||||||
|
methods: {
|
||||||
|
// 单选按钮值变化时
|
||||||
|
radioChange() {
|
||||||
|
if (this.cron.mouth === '*') {
|
||||||
|
this.$emit('update', 'mouth', '1', 'year');
|
||||||
|
}
|
||||||
|
if (this.cron.day === '*') {
|
||||||
|
this.$emit('update', 'day', '1', 'year');
|
||||||
|
}
|
||||||
|
if (this.cron.hour === '*') {
|
||||||
|
this.$emit('update', 'hour', '0', 'year');
|
||||||
|
}
|
||||||
|
if (this.cron.min === '*') {
|
||||||
|
this.$emit('update', 'min', '0', 'year');
|
||||||
|
}
|
||||||
|
if (this.cron.second === '*') {
|
||||||
|
this.$emit('update', 'second', '0', 'year');
|
||||||
|
}
|
||||||
|
switch (this.radioValue) {
|
||||||
|
case 1:
|
||||||
|
this.$emit('update', 'year', '');
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this.$emit('update', 'year', '*');
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
this.$emit('update', 'year', this.cycle01 + '-' + this.cycle02);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
this.$emit('update', 'year', this.average01 + '/' + this.average02);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
this.$emit('update', 'year', this.checkboxString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 周期两个值变化时
|
||||||
|
cycleChange() {
|
||||||
|
if (this.radioValue == '3') {
|
||||||
|
this.$emit('update', 'year', this.cycleTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 平均两个值变化时
|
||||||
|
averageChange() {
|
||||||
|
if (this.radioValue == '4') {
|
||||||
|
this.$emit('update', 'year', this.averageTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// checkbox值变化时
|
||||||
|
checkboxChange() {
|
||||||
|
if (this.radioValue == '5') {
|
||||||
|
this.$emit('update', 'year', this.checkboxString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
"radioValue": "radioChange",
|
||||||
|
'cycleTotal': 'cycleChange',
|
||||||
|
'averageTotal': 'averageChange',
|
||||||
|
'checkboxString': 'checkboxChange'
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 计算两个周期值
|
||||||
|
cycleTotal: function () {
|
||||||
|
this.cycle01 = this.checkNum(this.cycle01, this.fullYear, this.fullYear + 100)
|
||||||
|
this.cycle02 = this.checkNum(this.cycle02, this.fullYear + 1, this.fullYear + 101)
|
||||||
|
return this.cycle01 + '-' + this.cycle02;
|
||||||
|
},
|
||||||
|
// 计算平均用到的值
|
||||||
|
averageTotal: function () {
|
||||||
|
this.average01 = this.checkNum(this.average01, this.fullYear, this.fullYear + 100)
|
||||||
|
this.average02 = this.checkNum(this.average02, 1, 10)
|
||||||
|
return this.average01 + '/' + this.average02;
|
||||||
|
},
|
||||||
|
// 计算勾选的checkbox值合集
|
||||||
|
checkboxString: function () {
|
||||||
|
let str = this.checkboxList.join();
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted: function () {
|
||||||
|
// 仅获取当前年份
|
||||||
|
this.fullYear = Number(new Date().getFullYear());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -32,6 +32,7 @@ import TestCase from "../../track/case/TestCase";
|
||||||
import TestTrack from "../../track/TestTrack";
|
import TestTrack from "../../track/TestTrack";
|
||||||
import ApiReportList from "../../api/report/ApiReportList";
|
import ApiReportList from "../../api/report/ApiReportList";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import ApiKeys from "../../settings/personal/ApiKeys";
|
||||||
|
|
||||||
Vue.use(VueRouter);
|
Vue.use(VueRouter);
|
||||||
|
|
||||||
|
@ -70,6 +71,10 @@ const router = new VueRouter({
|
||||||
path: 'personsetting',
|
path: 'personsetting',
|
||||||
component: PersonSetting
|
component: PersonSetting
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'apikeys',
|
||||||
|
component: ApiKeys
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'member',
|
path: 'member',
|
||||||
component: Member
|
component: Member
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
<span>{{$t('commons.personal_info')}}</span>
|
<span>{{$t('commons.personal_info')}}</span>
|
||||||
</template>
|
</template>
|
||||||
<el-menu-item index="/setting/personsetting">{{$t('commons.personal_setting')}}</el-menu-item>
|
<el-menu-item index="/setting/personsetting">{{$t('commons.personal_setting')}}</el-menu-item>
|
||||||
|
<el-menu-item index="/setting/apikeys">API Keys</el-menu-item>
|
||||||
</el-submenu>
|
</el-submenu>
|
||||||
|
|
||||||
</el-menu>
|
</el-menu>
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
<template>
|
||||||
|
<div v-loading="result.loading">
|
||||||
|
<el-card class="table-card">
|
||||||
|
<template v-slot:header>
|
||||||
|
<div>
|
||||||
|
<el-row class="table-title" type="flex" justify="space-between" align="middle">
|
||||||
|
<span class="title">API Keys</span>
|
||||||
|
</el-row>
|
||||||
|
<el-row type="flex" justify="space-between" align="middle">
|
||||||
|
<el-button @click="createApiKey()" plain type="el-icon-question" icon="el-icon-circle-plus-outline"
|
||||||
|
size="mini">
|
||||||
|
{{$t('commons.create')}}
|
||||||
|
</el-button>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-table :data="tableData" style="width: 100%">
|
||||||
|
<el-table-column prop="accessKey" label="Access Key"/>
|
||||||
|
<el-table-column prop="secretKey" label="Secret Key"/>
|
||||||
|
<el-table-column prop="status" :label="$t('commons.status')">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<el-switch v-model="scope.row.status"
|
||||||
|
active-color="#13ce66"
|
||||||
|
inactive-color="#ff4949"
|
||||||
|
active-value="ACTIVE"
|
||||||
|
inactive-value="DISABLED"
|
||||||
|
@change="changeSwitch(scope.row)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="createTime" :label="$t('commons.create_time')">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column :label="$t('commons.operating')">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<ms-table-operator-button :tip="$t('commons.delete')" icon="el-icon-delete"
|
||||||
|
type="danger" @exec="deleteApiKey(scope.row)"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MsDialogFooter from "../../common/components/MsDialogFooter";
|
||||||
|
import {getCurrentUser} from "../../../../common/js/utils";
|
||||||
|
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
|
||||||
|
import MsTableHeader from "../../common/components/MsTableHeader";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "MsApiKeys",
|
||||||
|
components: {MsDialogFooter, MsTableOperatorButton, MsTableHeader},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
result: {},
|
||||||
|
updateVisible: false,
|
||||||
|
editPasswordVisible: false,
|
||||||
|
apiKeysVisible: false,
|
||||||
|
condition: {},
|
||||||
|
tableData: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
activated() {
|
||||||
|
this.search();
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
currentUser: () => {
|
||||||
|
return getCurrentUser();
|
||||||
|
},
|
||||||
|
search() {
|
||||||
|
this.result = this.$get("/user/key/info", response => {
|
||||||
|
this.tableData = response.data;
|
||||||
|
this.tableData.forEach(d => d.show = false);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
deleteApiKey(row) {
|
||||||
|
this.$confirm(this.$t('user.apikey_delete_confirm'), '', {
|
||||||
|
confirmButtonText: this.$t('commons.confirm'),
|
||||||
|
cancelButtonText: this.$t('commons.cancel'),
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
this.result = this.$get("/user/key/delete/" + row.id, response => {
|
||||||
|
this.$success(this.$t('commons.delete_success'));
|
||||||
|
this.search();
|
||||||
|
})
|
||||||
|
}).catch(() => {
|
||||||
|
this.$info(this.$t('commons.delete_cancel'));
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
createApiKey() {
|
||||||
|
this.result = this.$get("/user/key/generate", response => {
|
||||||
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
this.search();
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
changeSwitch(row) {
|
||||||
|
if (row.status === 'ACTIVE') {
|
||||||
|
this.result = this.$get("/user/key/active/" + row.id, response => {
|
||||||
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (row.status === 'DISABLED') {
|
||||||
|
this.result = this.$get("/user/key/disable/" + row.id, response => {
|
||||||
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,334 @@
|
||||||
|
/**
|
||||||
|
* Validates a cron expression.
|
||||||
|
*
|
||||||
|
* @param cronExpression The expression to validate
|
||||||
|
* @return True is expression is valid
|
||||||
|
*/
|
||||||
|
export function cronValidate(cronExpression ){
|
||||||
|
//alert("校验函数的开始!");
|
||||||
|
var cronParams = cronExpression.split(" ");
|
||||||
|
|
||||||
|
if (cronParams.length < 6 || cronParams.length > 7) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//CronTrigger cronTrigger = new CronTrigger();
|
||||||
|
//cronTrigger.setCronExpression( cronExpression );
|
||||||
|
|
||||||
|
if (cronParams[3] == "?" || cronParams[5]=="?") {
|
||||||
|
//Check seconds param
|
||||||
|
if (!checkSecondsField(cronParams[0])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check minutes param
|
||||||
|
if (!checkMinutesField(cronParams[1])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check hours param
|
||||||
|
if (!checkHoursField(cronParams[2])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check day-of-month param
|
||||||
|
if (!checkDayOfMonthField(cronParams[3])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check months param
|
||||||
|
if (!checkMonthsField(cronParams[4])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check day-of-week param
|
||||||
|
if (!checkDayOfWeekField(cronParams[5])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check year param
|
||||||
|
if (cronParams.length == 7) {
|
||||||
|
if (!checkYearField(cronParams[6])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkSecondsField(secondsField) {
|
||||||
|
return checkField(secondsField, 0, 59);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function checkField(secondsField, minimal, maximal) {
|
||||||
|
if (secondsField.indexOf("-") > -1 ) {
|
||||||
|
var startValue = secondsField.substring(0, secondsField.indexOf( "-" ));
|
||||||
|
var endValue = secondsField.substring(secondsField.indexOf( "-" ) + 1);
|
||||||
|
|
||||||
|
if (!(checkIntValue(startValue, minimal, maximal, true) && checkIntValue(endValue, minimal, maximal, true))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var startVal = parseInt(startValue, 10);
|
||||||
|
var endVal = parseInt(endValue, 10);
|
||||||
|
|
||||||
|
return endVal > startVal;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (secondsField.indexOf(",") > -1) {
|
||||||
|
return checkListField(secondsField, minimal, maximal);
|
||||||
|
} else if (secondsField.indexOf( "/" ) > -1) {
|
||||||
|
return checkIncrementField( secondsField, minimal, maximal );
|
||||||
|
} else if (secondsField.indexOf( "*" ) != -1) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return checkIntValue(secondsField, minimal, maximal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkIntValue(value, minimal, maximal, checkExtremity) {
|
||||||
|
try {
|
||||||
|
var val = parseInt(value, 10);
|
||||||
|
//判断是否为整数
|
||||||
|
if (value == val) {
|
||||||
|
if (checkExtremity) {
|
||||||
|
if (val < minimal || val > maximal) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkMinutesField(minutesField) {
|
||||||
|
return checkField(minutesField, 0, 59);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkHoursField(hoursField) {
|
||||||
|
return checkField(hoursField, 0, 23);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkDayOfMonthField(dayOfMonthField) {
|
||||||
|
if (dayOfMonthField == "?") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dayOfMonthField.indexOf("L") >= 0) {
|
||||||
|
return checkFieldWithLetter(dayOfMonthField, "L", 1, 7, -1, -1);
|
||||||
|
} else if ( dayOfMonthField.indexOf("W") >= 0) {
|
||||||
|
return checkFieldWithLetter(dayOfMonthField, "W", 1, 31, -1, -1);
|
||||||
|
} else if (dayOfMonthField.indexOf("C") >= 0) {
|
||||||
|
return checkFieldWithLetter(dayOfMonthField, "C", 1, 31, -1, -1);
|
||||||
|
} else {
|
||||||
|
return checkField( dayOfMonthField, 1, 31 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function checkMonthsField(monthsField) {
|
||||||
|
/* monthsField = StringUtils.replace( monthsField, "JAN", "1" );
|
||||||
|
monthsField = StringUtils.replace( monthsField, "FEB", "2" );
|
||||||
|
monthsField = StringUtils.replace( monthsField, "MAR", "3" );
|
||||||
|
monthsField = StringUtils.replace( monthsField, "APR", "4" );
|
||||||
|
monthsField = StringUtils.replace( monthsField, "MAY", "5" );
|
||||||
|
monthsField = StringUtils.replace( monthsField, "JUN", "6" );
|
||||||
|
monthsField = StringUtils.replace( monthsField, "JUL", "7" );
|
||||||
|
monthsField = StringUtils.replace( monthsField, "AUG", "8" );
|
||||||
|
monthsField = StringUtils.replace( monthsField, "SEP", "9" );
|
||||||
|
monthsField = StringUtils.replace( monthsField, "OCT", "10" );
|
||||||
|
monthsField = StringUtils.replace( monthsField, "NOV", "11" );
|
||||||
|
monthsField = StringUtils.replace( monthsField, "DEC", "12" );*/
|
||||||
|
|
||||||
|
monthsField.replace("JAN", "1");
|
||||||
|
monthsField.replace("FEB", "2");
|
||||||
|
monthsField.replace("MAR", "3");
|
||||||
|
monthsField.replace("APR", "4");
|
||||||
|
monthsField.replace("MAY", "5");
|
||||||
|
monthsField.replace("JUN", "6");
|
||||||
|
monthsField.replace("JUL", "7");
|
||||||
|
monthsField.replace("AUG", "8");
|
||||||
|
monthsField.replace("SEP", "9");
|
||||||
|
monthsField.replace("OCT", "10");
|
||||||
|
monthsField.replace("NOV", "11");
|
||||||
|
monthsField.replace("DEC", "12");
|
||||||
|
|
||||||
|
return checkField(monthsField, 1, 31);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkDayOfWeekField(dayOfWeekField) {
|
||||||
|
/* dayOfWeekField = StringUtils.replace( dayOfWeekField, "SUN", "1" );
|
||||||
|
dayOfWeekField = StringUtils.replace( dayOfWeekField, "MON", "2" );
|
||||||
|
dayOfWeekField = StringUtils.replace( dayOfWeekField, "TUE", "3" );
|
||||||
|
dayOfWeekField = StringUtils.replace( dayOfWeekField, "WED", "4" );
|
||||||
|
dayOfWeekField = StringUtils.replace( dayOfWeekField, "THU", "5" );
|
||||||
|
dayOfWeekField = StringUtils.replace( dayOfWeekField, "FRI", "6" );
|
||||||
|
dayOfWeekField = StringUtils.replace( dayOfWeekField, "SAT", "7" );*/
|
||||||
|
|
||||||
|
dayOfWeekField.replace("SUN", "1" );
|
||||||
|
dayOfWeekField.replace("MON", "2" );
|
||||||
|
dayOfWeekField.replace("TUE", "3" );
|
||||||
|
dayOfWeekField.replace("WED", "4" );
|
||||||
|
dayOfWeekField.replace("THU", "5" );
|
||||||
|
dayOfWeekField.replace("FRI", "6" );
|
||||||
|
dayOfWeekField.replace("SAT", "7" );
|
||||||
|
|
||||||
|
if (dayOfWeekField == "?") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dayOfWeekField.indexOf("L") >= 0) {
|
||||||
|
return checkFieldWithLetter(dayOfWeekField, "L", 1, 7, -1, -1);
|
||||||
|
} else if (dayOfWeekField.indexOf("C") >= 0) {
|
||||||
|
return checkFieldWithLetter(dayOfWeekField, "C", 1, 7, -1, -1);
|
||||||
|
} else if (dayOfWeekField.indexOf("#") >= 0) {
|
||||||
|
return checkFieldWithLetter(dayOfWeekField, "#", 1, 7, 1, 5);
|
||||||
|
} else {
|
||||||
|
return checkField(dayOfWeekField, 1, 7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkYearField(yearField) {
|
||||||
|
return checkField(yearField, 1970, 2099);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function checkFieldWithLetter(value, letter, minimalBefore, maximalBefore,
|
||||||
|
minimalAfter, maximalAfter) {
|
||||||
|
var canBeAlone = false;
|
||||||
|
var canHaveIntBefore = false;
|
||||||
|
var canHaveIntAfter = false;
|
||||||
|
var mustHaveIntBefore = false;
|
||||||
|
var mustHaveIntAfter = false;
|
||||||
|
|
||||||
|
if (letter == "L") {
|
||||||
|
canBeAlone = true;
|
||||||
|
canHaveIntBefore = true;
|
||||||
|
canHaveIntAfter = false;
|
||||||
|
mustHaveIntBefore = false;
|
||||||
|
mustHaveIntAfter = false;
|
||||||
|
}
|
||||||
|
if (letter == "W" || letter == "C") {
|
||||||
|
canBeAlone = false;
|
||||||
|
canHaveIntBefore = true;
|
||||||
|
canHaveIntAfter = false;
|
||||||
|
mustHaveIntBefore = true;
|
||||||
|
mustHaveIntAfter = false;
|
||||||
|
}
|
||||||
|
if (letter == "#") {
|
||||||
|
canBeAlone = false;
|
||||||
|
canHaveIntBefore = true;
|
||||||
|
canHaveIntAfter = true;
|
||||||
|
mustHaveIntBefore = true;
|
||||||
|
mustHaveIntAfter = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var beforeLetter = "";
|
||||||
|
var afterLetter = "";
|
||||||
|
|
||||||
|
if (value.indexOf(letter) >= 0 ) {
|
||||||
|
beforeLetter = value.substring( 0, value.indexOf(letter));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!value.endsWith(letter)) {
|
||||||
|
afterLetter = value.substring( value.indexOf( letter ) + 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.indexOf(letter) >= 0) {
|
||||||
|
if (letter == value) {
|
||||||
|
return canBeAlone;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canHaveIntBefore) {
|
||||||
|
if (mustHaveIntBefore && beforeLetter.length == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!checkIntValue(beforeLetter, minimalBefore, maximalBefore, true)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (beforeLetter.length > 0 ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canHaveIntAfter) {
|
||||||
|
if ( mustHaveIntAfter && afterLetter.length == 0 ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!checkIntValue(afterLetter, minimalAfter, maximalAfter, true)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (afterLetter.length > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* function checkIntValue(value, minimal, maximal) {
|
||||||
|
return checkIntValue(value, minimal, maximal, true);
|
||||||
|
} */
|
||||||
|
|
||||||
|
function checkIncrementField(value, minimal, maximal) {
|
||||||
|
var start = value.substring(0, value.indexOf("/"));
|
||||||
|
|
||||||
|
var increment = value.substring(value.indexOf("/") + 1);
|
||||||
|
|
||||||
|
if (!("*" == start)) {
|
||||||
|
return checkIntValue(start, minimal, maximal, true) && checkIntValue(increment, minimal, maximal, false);
|
||||||
|
} else {
|
||||||
|
return checkIntValue(increment, minimal, maximal, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function checkListField(value, minimal, maximal ) {
|
||||||
|
var st = value.split(",");
|
||||||
|
|
||||||
|
var values = new Array(st.length);
|
||||||
|
|
||||||
|
for(var j = 0; j < st.length; j++) {
|
||||||
|
values[j] = st[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
var previousValue = -1;
|
||||||
|
|
||||||
|
for (var i= 0; i < values.length; i++) {
|
||||||
|
var currentValue = values[i];
|
||||||
|
|
||||||
|
if (!checkIntValue(currentValue, minimal, maximal, true)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
var val = parseInt(currentValue, 10);
|
||||||
|
|
||||||
|
if (val <= previousValue) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
previousValue = val;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// we have always an int
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -174,6 +174,7 @@ export default {
|
||||||
'mobile_number_format_is_incorrect': 'Mobile number format is incorrect',
|
'mobile_number_format_is_incorrect': 'Mobile number format is incorrect',
|
||||||
'email_format_is_incorrect': 'Email format is incorrect',
|
'email_format_is_incorrect': 'Email format is incorrect',
|
||||||
'delete_confirm': 'Are you sure you want to delete this User?',
|
'delete_confirm': 'Are you sure you want to delete this User?',
|
||||||
|
'apikey_delete_confirm': 'Are you sure you want to delete this API Key?',
|
||||||
'input_id_placeholder': 'Please enter ID (only supports numbers and English letters)'
|
'input_id_placeholder': 'Please enter ID (only supports numbers and English letters)'
|
||||||
},
|
},
|
||||||
role: {
|
role: {
|
||||||
|
|
|
@ -173,6 +173,7 @@ export default {
|
||||||
'mobile_number_format_is_incorrect': '手机号码格式不正确',
|
'mobile_number_format_is_incorrect': '手机号码格式不正确',
|
||||||
'email_format_is_incorrect': '邮箱格式不正确',
|
'email_format_is_incorrect': '邮箱格式不正确',
|
||||||
'delete_confirm': '这个用户确定要删除吗?',
|
'delete_confirm': '这个用户确定要删除吗?',
|
||||||
|
'apikey_delete_confirm': '这个 API Key 确定要删除吗?',
|
||||||
'input_id_placeholder': '请输入ID (只支持数字、英文字母)'
|
'input_id_placeholder': '请输入ID (只支持数字、英文字母)'
|
||||||
},
|
},
|
||||||
role: {
|
role: {
|
||||||
|
|
|
@ -171,6 +171,7 @@ export default {
|
||||||
'mobile_number_format_is_incorrect': '手機號碼格式不正確',
|
'mobile_number_format_is_incorrect': '手機號碼格式不正確',
|
||||||
'email_format_is_incorrect': '郵箱格式不正確',
|
'email_format_is_incorrect': '郵箱格式不正確',
|
||||||
'delete_confirm': '這個用戶確定要刪除嗎?',
|
'delete_confirm': '這個用戶確定要刪除嗎?',
|
||||||
|
'apikey_delete_confirm': '這個 API Key 確定要刪除嗎?',
|
||||||
'input_id_placeholder': '請輸入ID (只支持數字、英文字母)'
|
'input_id_placeholder': '請輸入ID (只支持數字、英文字母)'
|
||||||
},
|
},
|
||||||
role: {
|
role: {
|
||||||
|
|
Loading…
Reference in New Issue