Browse Source

Merge remote-tracking branch 'upstream/dev-20190415' into dev-20190415

pull/2/head
ligang 6 years ago
parent
commit
3cfb5d9824
  1. 2
      escheduler-alert/pom.xml
  2. 2
      escheduler-api/pom.xml
  3. 169
      escheduler-api/src/main/java/cn/escheduler/api/controller/AccessTokenController.java
  4. 1
      escheduler-api/src/main/java/cn/escheduler/api/controller/SchedulerController.java
  5. 6
      escheduler-api/src/main/java/cn/escheduler/api/enums/Status.java
  6. 43
      escheduler-api/src/main/java/cn/escheduler/api/interceptor/LoginHandlerInterceptor.java
  7. 2
      escheduler-api/src/main/java/cn/escheduler/api/quartz/ProcessScheduleJob.java
  8. 184
      escheduler-api/src/main/java/cn/escheduler/api/service/AccessTokenService.java
  9. 162
      escheduler-api/src/test/java/cn/escheduler/api/HttpClientTest.java
  10. 2
      escheduler-common/pom.xml
  11. 30
      escheduler-common/src/main/java/cn/escheduler/common/Constants.java
  12. 7
      escheduler-common/src/main/java/cn/escheduler/common/utils/CommonUtils.java
  13. 1
      escheduler-common/src/main/resources/common/common.properties
  14. 2
      escheduler-dao/pom.xml
  15. 33
      escheduler-dao/readme.txt
  16. 11
      escheduler-dao/src/main/java/cn/escheduler/dao/ProcessDao.java
  17. 88
      escheduler-dao/src/main/java/cn/escheduler/dao/mapper/AccessTokenMapper.java
  18. 130
      escheduler-dao/src/main/java/cn/escheduler/dao/mapper/AccessTokenMapperProvider.java
  19. 45
      escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ErrorCommandMapper.java
  20. 41
      escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ErrorCommandMapperProvider.java
  21. 20
      escheduler-dao/src/main/java/cn/escheduler/dao/mapper/UserMapper.java
  22. 16
      escheduler-dao/src/main/java/cn/escheduler/dao/mapper/UserMapperProvider.java
  23. 126
      escheduler-dao/src/main/java/cn/escheduler/dao/model/AccessToken.java
  24. 275
      escheduler-dao/src/main/java/cn/escheduler/dao/model/ErrorCommand.java
  25. 62
      escheduler-dao/src/test/java/cn/escheduler/dao/mapper/AccessTokenMapperTest.java
  26. 6
      escheduler-dao/src/test/java/cn/escheduler/dao/mapper/UserMapperTest.java
  27. 2
      escheduler-rpc/pom.xml
  28. 2
      escheduler-server/pom.xml
  29. 2
      escheduler-server/src/main/java/cn/escheduler/server/worker/runner/FetchTaskThread.java
  30. 73
      escheduler-server/src/main/java/cn/escheduler/server/worker/task/PythonCommandExecutor.java
  31. 2
      escheduler-server/src/main/java/cn/escheduler/server/worker/task/python/PythonTask.java
  32. 65
      escheduler-server/src/test/java/cn/escheduler/server/worker/EnvFileTest.java
  33. 87
      escheduler-ui/build/i18n.js
  34. 40
      escheduler-ui/src/js/conf/home/pages/monitor/index.vue
  35. 19
      escheduler-ui/src/js/conf/home/pages/projects/index.vue
  36. 35
      escheduler-ui/src/js/conf/home/pages/projects/pages/_source/taskRecordList/index.vue
  37. 5
      escheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/create/index.vue
  38. 5
      escheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/details/index.vue
  39. 2
      escheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/email.vue
  40. 41
      escheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/index.vue
  41. 99
      escheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/tree/index.vue
  42. 13
      escheduler-ui/src/js/conf/home/pages/projects/pages/definition/timing/index.vue
  43. 27
      escheduler-ui/src/js/conf/home/pages/projects/pages/index/index.vue
  44. 24
      escheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/details/index.vue
  45. 49
      escheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/gantt/index.vue
  46. 35
      escheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/list/index.vue
  47. 35
      escheduler-ui/src/js/conf/home/pages/projects/pages/taskInstance/index.vue
  48. 9
      escheduler-ui/src/js/conf/home/pages/resource/index.vue
  49. 122
      escheduler-ui/src/js/conf/home/pages/resource/pages/file/pages/create/index.vue
  50. 52
      escheduler-ui/src/js/conf/home/pages/resource/pages/file/pages/details/index.vue
  51. 56
      escheduler-ui/src/js/conf/home/pages/resource/pages/file/pages/edit/index.vue
  52. 54
      escheduler-ui/src/js/conf/home/pages/resource/pages/file/pages/list/index.vue
  53. 48
      escheduler-ui/src/js/conf/home/pages/resource/pages/udf/pages/function/index.vue
  54. 8
      escheduler-ui/src/js/conf/home/pages/resource/pages/udf/pages/resource/index.vue
  55. 9
      escheduler-ui/src/js/conf/home/pages/security/index.vue
  56. 46
      escheduler-ui/src/js/conf/home/pages/security/pages/queue/index.vue
  57. 30
      escheduler-ui/src/js/conf/home/pages/security/pages/servers/pages/master/index.vue
  58. 26
      escheduler-ui/src/js/conf/home/pages/security/pages/servers/pages/worker/index.vue
  59. 46
      escheduler-ui/src/js/conf/home/pages/security/pages/tenement/index.vue
  60. 50
      escheduler-ui/src/js/conf/home/pages/security/pages/users/index.vue
  61. 46
      escheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/index.vue
  62. 10
      escheduler-ui/src/js/conf/home/pages/user/index.vue
  63. 16
      escheduler-ui/src/js/conf/home/pages/user/pages/account/index.vue
  64. 16
      escheduler-ui/src/js/conf/home/pages/user/pages/password/index.vue
  65. 152
      escheduler-ui/src/js/conf/home/pages/user/pages/token/_source/createToken.vue
  66. 125
      escheduler-ui/src/js/conf/home/pages/user/pages/token/_source/list.vue
  67. 115
      escheduler-ui/src/js/conf/home/pages/user/pages/token/index.vue
  68. 8
      escheduler-ui/src/js/conf/home/router/index.js
  69. 14
      escheduler-ui/src/js/conf/home/store/security/actions.js
  70. 77
      escheduler-ui/src/js/conf/home/store/user/actions.js
  71. 6
      escheduler-ui/src/js/module/components/conditions/conditions.vue
  72. 4
      escheduler-ui/src/js/module/components/nav/nav.vue
  73. 0
      escheduler-ui/src/js/module/components/secondaryMenu/_source/close.png
  74. 56
      escheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js
  75. 0
      escheduler-ui/src/js/module/components/secondaryMenu/_source/open.png
  76. 49
      escheduler-ui/src/js/module/components/secondaryMenu/secondaryMenu.vue
  77. 2
      escheduler-ui/src/js/module/i18n/locale/zh_CN.js
  78. 7
      escheduler-ui/src/lib/external/config.js
  79. 0
      escheduler-ui/src/lib/external/email.js
  80. 3
      escheduler-ui/src/sass/common/index.scss
  81. 2
      pom.xml
  82. 12
      script/env/escheduler_env.py

2
escheduler-alert/pom.xml

@ -4,7 +4,7 @@
<parent>
<groupId>cn.analysys</groupId>
<artifactId>escheduler</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>1.0.1-SNAPSHOT</version>
</parent>
<artifactId>escheduler-alert</artifactId>
<packaging>jar</packaging>

2
escheduler-api/pom.xml

@ -3,7 +3,7 @@
<parent>
<groupId>cn.analysys</groupId>
<artifactId>escheduler</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>1.0.1-SNAPSHOT</version>
</parent>
<artifactId>escheduler-api</artifactId>
<packaging>jar</packaging>

169
escheduler-api/src/main/java/cn/escheduler/api/controller/AccessTokenController.java

@ -0,0 +1,169 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.escheduler.api.controller;
import cn.escheduler.api.enums.Status;
import cn.escheduler.api.service.AccessTokenService;
import cn.escheduler.api.service.UsersService;
import cn.escheduler.api.utils.Constants;
import cn.escheduler.api.utils.Result;
import cn.escheduler.dao.model.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
import static cn.escheduler.api.enums.Status.*;
/**
* user controller
*/
@RestController
@RequestMapping("/access-token")
public class AccessTokenController extends BaseController{
private static final Logger logger = LoggerFactory.getLogger(AccessTokenController.class);
@Autowired
private AccessTokenService accessTokenService;
/**
* create token
* @param loginUser
* @return
*/
@PostMapping(value = "/create")
@ResponseStatus(HttpStatus.CREATED)
public Result createToken(@RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@RequestParam(value = "userId") int userId,
@RequestParam(value = "expireTime") String expireTime,
@RequestParam(value = "token") String token){
logger.info("login user {}, create token , userId : {} , token expire time : {} , token : {}", loginUser.getUserName(),
userId,expireTime,token);
try {
Map<String, Object> result = accessTokenService.createToken(userId, expireTime, token);
return returnDataList(result);
}catch (Exception e){
logger.error(CREATE_ACCESS_TOKEN_ERROR.getMsg(),e);
return error(CREATE_ACCESS_TOKEN_ERROR.getCode(), CREATE_ACCESS_TOKEN_ERROR.getMsg());
}
}
/**
* create token
* @param loginUser
* @return
*/
@PostMapping(value = "/generate")
@ResponseStatus(HttpStatus.CREATED)
public Result generateToken(@RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@RequestParam(value = "userId") int userId,
@RequestParam(value = "expireTime") String expireTime){
logger.info("login user {}, generate token , userId : {} , token expire time : {}",loginUser,userId,expireTime);
try {
Map<String, Object> result = accessTokenService.generateToken(userId, expireTime);
return returnDataList(result);
}catch (Exception e){
logger.error(GENERATE_TOKEN_ERROR.getMsg(),e);
return error(GENERATE_TOKEN_ERROR.getCode(), GENERATE_TOKEN_ERROR.getMsg());
}
}
/**
* query access token list paging
*
* @param loginUser
* @param pageNo
* @param searchVal
* @param pageSize
* @return
*/
@GetMapping(value="/list-paging")
@ResponseStatus(HttpStatus.OK)
public Result queryAccessTokenList(@RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@RequestParam("pageNo") Integer pageNo,
@RequestParam(value = "searchVal", required = false) String searchVal,
@RequestParam("pageSize") Integer pageSize){
logger.info("login user {}, list access token paging, pageNo: {}, searchVal: {}, pageSize: {}",
loginUser.getUserName(),pageNo,searchVal,pageSize);
try{
Map<String, Object> result = checkPageParams(pageNo, pageSize);
if(result.get(Constants.STATUS) != Status.SUCCESS){
return returnDataListPaging(result);
}
result = accessTokenService.queryAccessTokenList(loginUser, searchVal, pageNo, pageSize);
return returnDataListPaging(result);
}catch (Exception e){
logger.error(QUERY_ACCESSTOKEN_LIST_PAGING_ERROR.getMsg(),e);
return error(QUERY_ACCESSTOKEN_LIST_PAGING_ERROR.getCode(),QUERY_ACCESSTOKEN_LIST_PAGING_ERROR.getMsg());
}
}
/**
* delete access token by id
* @param loginUser
* @param id
* @return
*/
@PostMapping(value = "/delete")
@ResponseStatus(HttpStatus.OK)
public Result delAccessTokenById(@RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@RequestParam(value = "id") int id) {
logger.info("login user {}, delete access token, id: {},", loginUser.getUserName(), id);
try {
Map<String, Object> result = accessTokenService.delAccessTokenById(loginUser, id);
return returnDataList(result);
}catch (Exception e){
logger.error(DELETE_USER_BY_ID_ERROR.getMsg(),e);
return error(Status.DELETE_USER_BY_ID_ERROR.getCode(), Status.DELETE_USER_BY_ID_ERROR.getMsg());
}
}
/**
* update token
* @param loginUser
* @return
*/
@PostMapping(value = "/update")
@ResponseStatus(HttpStatus.CREATED)
public Result updateToken(@RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@RequestParam(value = "id") int id,
@RequestParam(value = "userId") int userId,
@RequestParam(value = "expireTime") String expireTime,
@RequestParam(value = "token") String token){
logger.info("login user {}, update token , userId : {} , token expire time : {} , token : {}", loginUser.getUserName(),
userId,expireTime,token);
try {
Map<String, Object> result = accessTokenService.updateToken(id,userId, expireTime, token);
return returnDataList(result);
}catch (Exception e){
logger.error(CREATE_ACCESS_TOKEN_ERROR.getMsg(),e);
return error(CREATE_ACCESS_TOKEN_ERROR.getCode(), CREATE_ACCESS_TOKEN_ERROR.getMsg());
}
}
}

1
escheduler-api/src/main/java/cn/escheduler/api/controller/SchedulerController.java

@ -46,7 +46,6 @@ public class SchedulerController extends BaseController{
private static final Logger logger = LoggerFactory.getLogger(SchedulerController.class);
public static final String DEFAULT_WARNING_TYPE = "NONE";
public static final String DEFAULT_NOTIFY_GROUP_ID = "1";
public static final String DEFAULT_MAX_TRY_TIMES = "0";
public static final String DEFAULT_FAILURE_POLICY = "CONTINUE";

6
escheduler-api/src/main/java/cn/escheduler/api/enums/Status.java

@ -199,6 +199,12 @@ public enum Status {
HDFS_NOT_STARTUP(60001,"hdfs not startup"),
CREATE_ACCESS_TOKEN_ERROR(70001,"create access token error"),
GENERATE_TOKEN_ERROR(70002,"generate token error"),
QUERY_ACCESSTOKEN_LIST_PAGING_ERROR(70003,"query access token list paging error"),
;
private int code;

43
escheduler-api/src/main/java/cn/escheduler/api/interceptor/LoginHandlerInterceptor.java

@ -22,6 +22,7 @@ import cn.escheduler.dao.mapper.UserMapper;
import cn.escheduler.dao.model.Session;
import cn.escheduler.dao.model.User;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -64,37 +65,31 @@ public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
Session session = sessionService.getSession(request);
if(logger.isDebugEnabled()){
logger.debug("session info : " + session);
}
if (session == null) {
response.setStatus(HttpStatus.SC_UNAUTHORIZED);
logger.info("session info is null ");
return false;
}
if(logger.isDebugEnabled()){
logger.debug("session id: {}", session.getId());
// get token
String token = request.getHeader("token");
User user = null;
if (StringUtils.isEmpty(token)){
Session session = sessionService.getSession(request);
if (session == null) {
response.setStatus(HttpStatus.SC_UNAUTHORIZED);
logger.info("session info is null ");
return false;
}
//get user object from session
user = userMapper.queryById(session.getUserId());
}else {
user = userMapper.queryUserByToken(token);
}
//get user object from session
User user = userMapper.queryById(session.getUserId());
if(logger.isDebugEnabled()){
logger.info("user info : " + user);
}
// if user is null
if (user == null) {
response.setStatus(HttpStatus.SC_UNAUTHORIZED);
logger.info("user does not exist");
return false;
}
request.setAttribute(Constants.SESSION_USER, user);
return true;
}

2
escheduler-api/src/main/java/cn/escheduler/api/quartz/ProcessScheduleJob.java

@ -125,7 +125,7 @@ public class ProcessScheduleJob implements Job {
}
Command command = new Command();
command.setCommandType(CommandType.START_PROCESS);
command.setCommandType(CommandType.SCHEDULER);
command.setExecutorId(schedule.getUserId());
command.setFailureStrategy(schedule.getFailureStrategy());
command.setProcessDefinitionId(schedule.getProcessDefinitionId());

184
escheduler-api/src/main/java/cn/escheduler/api/service/AccessTokenService.java

@ -0,0 +1,184 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.escheduler.api.service;
import cn.escheduler.api.enums.Status;
import cn.escheduler.api.utils.CheckUtils;
import cn.escheduler.api.utils.Constants;
import cn.escheduler.api.utils.PageInfo;
import cn.escheduler.api.utils.Result;
import cn.escheduler.common.enums.UserType;
import cn.escheduler.common.utils.*;
import cn.escheduler.dao.mapper.*;
import cn.escheduler.dao.model.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
/**
* user service
*/
@Service
public class AccessTokenService extends BaseService {
private static final Logger logger = LoggerFactory.getLogger(AccessTokenService.class);
@Autowired
private AccessTokenMapper accessTokenMapper;
/**
* query access token list
*
* @param loginUser
* @param searchVal
* @param pageNo
* @param pageSize
* @return
*/
public Map<String, Object> queryAccessTokenList(User loginUser, String searchVal, Integer pageNo, Integer pageSize) {
Map<String, Object> result = new HashMap<>(5);
if (check(result, !isAdmin(loginUser), Status.USER_NO_OPERATION_PERM, Constants.STATUS)) {
return result;
}
Integer count = accessTokenMapper.countAccessTokenPaging(searchVal);
PageInfo<AccessToken> pageInfo = new PageInfo<>(pageNo, pageSize);
List<AccessToken> accessTokenList = accessTokenMapper.queryAccessTokenPaging(searchVal, pageInfo.getStart(), pageSize);
pageInfo.setTotalCount(count);
pageInfo.setLists(accessTokenList);
result.put(Constants.DATA_LIST, pageInfo);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* check
*
* @param result
* @param bool
* @param userNoOperationPerm
* @param status
* @return
*/
private boolean check(Map<String, Object> result, boolean bool, Status userNoOperationPerm, String status) {
//only admin can operate
if (bool) {
result.put(Constants.STATUS, userNoOperationPerm);
result.put(status, userNoOperationPerm.getMsg());
return true;
}
return false;
}
/**
* create token
*
* @param userId
* @param expireTime
* @param token
* @return
*/
public Map<String, Object> createToken(int userId, String expireTime, String token) {
Map<String, Object> result = new HashMap<>(5);
AccessToken accessToken = new AccessToken();
accessToken.setUserId(userId);
accessToken.setExpireTime(DateUtils.stringToDate(expireTime));
accessToken.setToken(token);
accessToken.setCreateTime(new Date());
accessToken.setUpdateTime(new Date());
// insert
int insert = accessTokenMapper.insert(accessToken);
if (insert > 0) {
putMsg(result, Status.SUCCESS);
} else {
putMsg(result, Status.CREATE_ALERT_GROUP_ERROR);
}
return result;
}
/**
* generate token
* @param userId
* @param expireTime
* @return
*/
public Map<String, Object> generateToken(int userId, String expireTime) {
Map<String, Object> result = new HashMap<>(5);
String token = EncryptionUtils.getMd5(userId + expireTime + String.valueOf(System.currentTimeMillis()));
result.put(Constants.DATA_LIST, token);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* delete access token
* @param loginUser
* @param id
* @return
*/
public Map<String, Object> delAccessTokenById(User loginUser, int id) {
Map<String, Object> result = new HashMap<>(5);
//only admin can operate
if (!isAdmin(loginUser)) {
putMsg(result, Status.USER_NOT_EXIST, id);
return result;
}
accessTokenMapper.delete(id);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* update token by id
* @param id
* @param userId
* @param expireTime
* @param token
* @return
*/
public Map<String, Object> updateToken(int id,int userId, String expireTime, String token) {
Map<String, Object> result = new HashMap<>(5);
AccessToken accessToken = new AccessToken();
accessToken.setId(id);
accessToken.setUserId(userId);
accessToken.setExpireTime(DateUtils.stringToDate(expireTime));
accessToken.setToken(token);
accessToken.setUpdateTime(new Date());
accessTokenMapper.update(accessToken);
putMsg(result, Status.SUCCESS);
return result;
}
}

162
escheduler-api/src/test/java/cn/escheduler/api/HttpClientTest.java

@ -0,0 +1,162 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.escheduler.api;
import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import cn.escheduler.common.utils.EncryptionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HttpClientTest {
private static final Logger logger = LoggerFactory.getLogger(HttpClientTest.class);
public static void main(String[] args) throws Exception {
// doGETParamPathVariableAndChinese();
// doGETParam();
// doPOSTParam();
String md5 = EncryptionUtils.getMd5(String.valueOf(System.currentTimeMillis()) + "张三");
System.out.println(md5);
System.out.println(md5.length());
}
public static void doPOSTParam()throws Exception{
// create Httpclient
CloseableHttpClient httpclient = HttpClients.createDefault();
// 创建http POST请求
HttpPost httpPost = new HttpPost("http://127.0.0.1:12345/escheduler/projects/create");
httpPost.setHeader("token", "123");
// set parameters
List<NameValuePair> parameters = new ArrayList<NameValuePair>();
parameters.add(new BasicNameValuePair("projectName", "qzw"));
parameters.add(new BasicNameValuePair("desc", "qzw"));
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters);
httpPost.setEntity(formEntity);
CloseableHttpResponse response = null;
try {
// execute
response = httpclient.execute(httpPost);
// eponse status code 200
if (response.getStatusLine().getStatusCode() == 200) {
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
System.out.println(content);
}
} finally {
if (response != null) {
response.close();
}
httpclient.close();
}
}
/**
*
* @throws Exception
*/
public static void doGETParamPathVariableAndChinese()throws Exception{
// create HttpClient
CloseableHttpClient httpclient = HttpClients.createDefault();
List<NameValuePair> parameters = new ArrayList<NameValuePair>();
// parameters.add(new BasicNameValuePair("pageSize", "10"));
// define the parameters of the request
URI uri = new URIBuilder("http://127.0.0.1:12345/escheduler/projects/%E5%85%A8%E9%83%A8%E6%B5%81%E7%A8%8B%E6%B5%8B%E8%AF%95/process/list")
.build();
// create http GET request
HttpGet httpGet = new HttpGet(uri);
httpGet.setHeader("token","123");
//response object
CloseableHttpResponse response = null;
try {
// execute http get request
response = httpclient.execute(httpGet);
// reponse status code 200
if (response.getStatusLine().getStatusCode() == 200) {
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
logger.info("start--------------->");
logger.info(content);
logger.info("end----------------->");
}
} finally {
if (response != null) {
response.close();
}
httpclient.close();
}
}
/**
*
* @throws Exception
*/
public static void doGETParam()throws Exception{
// create HttpClient
CloseableHttpClient httpclient = HttpClients.createDefault();
List<NameValuePair> parameters = new ArrayList<NameValuePair>();
parameters.add(new BasicNameValuePair("processInstanceId", "41415"));
// define the parameters of the request
URI uri = new URIBuilder("http://127.0.0.1:12345/escheduler/projects/%E5%85%A8%E9%83%A8%E6%B5%81%E7%A8%8B%E6%B5%8B%E8%AF%95/instance/view-variables")
.setParameters(parameters)
.build();
// create http GET request
HttpGet httpGet = new HttpGet(uri);
httpGet.setHeader("token","123");
//response object
CloseableHttpResponse response = null;
try {
// execute http get request
response = httpclient.execute(httpGet);
// reponse status code 200
if (response.getStatusLine().getStatusCode() == 200) {
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
logger.info("start--------------->");
logger.info(content);
logger.info("end----------------->");
}
} finally {
if (response != null) {
response.close();
}
httpclient.close();
}
}
}

2
escheduler-common/pom.xml

@ -4,7 +4,7 @@
<parent>
<artifactId>escheduler</artifactId>
<groupId>cn.analysys</groupId>
<version>1.0.0-SNAPSHOT</version>
<version>1.0.1-SNAPSHOT</version>
</parent>
<artifactId>escheduler-common</artifactId>
<name>escheduler-common</name>

30
escheduler-common/src/main/java/cn/escheduler/common/Constants.java

@ -70,25 +70,6 @@ public final class Constants {
*/
public static final String YARN_APPLICATION_STATUS_ADDRESS = "yarn.application.status.address";
/**
* spring.redis.maxIdle
*/
public static final String SPRING_REDIS_MAXIDLE = "spring.redis.maxIdle";
/**
* spring.redis.maxTotal
*/
public static final String SPRING_REDIS_MAXTOTAL = "spring.redis.maxTotal";
/**
* spring.redis.host
*/
public static final String SPRING_REDIS_HOST = "spring.redis.host";
/**
* spring.redis.port
*/
public static final String SPRING_REDIS_PORT = "spring.redis.port";
/**
* hdfs configuration
@ -117,9 +98,14 @@ public final class Constants {
public static final String ESCHEDULER_ENV_PATH = "escheduler.env.path";
/**
* escheduler.env.py
* escheduler.env.sh
*/
public static final String ESCHEDULER_ENV_PY = "escheduler.env.py";
public static final String ESCHEDULER_ENV_SH = ".escheduler_env.sh";
/**
* python home
*/
public static final String PYTHON_HOME="PYTHON_HOME";
/**
* resource.view.suffixs
@ -255,8 +241,6 @@ public final class Constants {
public static final String SCHEDULER_QUEUE_IMPL = "escheduler.queue.impl";
public static final String SCHEDULER_QUEUE_REDIS_IMPL = "redis";
/**
* date format of yyyy-MM-dd HH:mm:ss

7
escheduler-common/src/main/java/cn/escheduler/common/utils/CommonUtils.java

@ -46,13 +46,6 @@ public class CommonUtils {
return envPath;
}
/**
* @return get the path of Python system environment variables
*/
public static String getPythonSystemEnvPath() {
return getString(ESCHEDULER_ENV_PY);
}
/**
* @return get queue implementation name
*/

1
escheduler-common/src/main/resources/common/common.properties

@ -18,7 +18,6 @@ hdfs.startup.state=true
# system env path. self configuration, please make sure the directory and file exists and have read write execute permissions
escheduler.env.path=/opt/.escheduler_env.sh
escheduler.env.py=/opt/escheduler_env.py
#resource.view.suffixs
resource.view.suffixs=txt,log,sh,conf,cfg,py,java,sql,hql,xml

2
escheduler-dao/pom.xml

@ -4,7 +4,7 @@
<parent>
<groupId>cn.analysys</groupId>
<artifactId>escheduler</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>1.0.1-SNAPSHOT</version>
</parent>
<artifactId>escheduler-dao</artifactId>
<name>escheduler-dao</name>

33
escheduler-dao/readme.txt

@ -1 +1,32 @@
alter table t_escheduler_user add queue varchar(64);
-- 用户指定队列
alter table t_escheduler_user add queue varchar(64);
-- 访问token
CREATE TABLE `t_escheduler_access_token` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`user_id` int(11) DEFAULT NULL COMMENT '用户id',
`token` varchar(64) DEFAULT NULL COMMENT 'token令牌',
`expire_time` datetime DEFAULT NULL COMMENT 'token有效结束时间',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
CREATE TABLE `escheduler`.`t_escheduler_error_command` (
`id` int(11) NOT NULL COMMENT '主键',
`command_type` tinyint(4) NULL DEFAULT NULL COMMENT '命令类型:0 启动工作流,1 从当前节点开始执行,2 恢复被容错的工作流,3 恢复暂停流程 4 从失败节点开始执行',
`executor_id` int(11) NULL DEFAULT NULL COMMENT '命令执行者',
`process_definition_id` int(11) NULL DEFAULT NULL COMMENT '流程定义id',
`command_param` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '命令的参数(json格式)',
`task_depend_type` tinyint(4) NULL DEFAULT NULL COMMENT '节点依赖类型',
`failure_strategy` tinyint(4) NULL DEFAULT 0 COMMENT '失败策略:0结束,1继续',
`warning_type` tinyint(4) NULL DEFAULT 0 COMMENT '告警类型',
`warning_group_id` int(11) NULL DEFAULT NULL COMMENT '告警组',
`schedule_time` datetime(0) NULL DEFAULT NULL COMMENT '预期运行时间',
`start_time` datetime(0) NULL DEFAULT NULL COMMENT '开始时间',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
`dependence` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '依赖字段',
`process_instance_priority` int(11) NULL DEFAULT NULL COMMENT '流程实例优先级:0 Highest,1 High,2 Medium,3 Low,4 Lowest',
`message` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '执行信息',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

11
escheduler-dao/src/main/java/cn/escheduler/dao/ProcessDao.java

@ -88,6 +88,9 @@ public class ProcessDao extends AbstractBaseDao {
@Autowired
private ResourceMapper resourceMapper;
@Autowired
private ErrorCommandMapper errorCommandMapper;
/**
* task queue impl
*/
@ -139,6 +142,7 @@ public class ProcessDao extends AbstractBaseDao {
if(processInstance == null){
logger.error("scan command, command parameter is error: %s", command.toString());
delCommandByid(command.getId());
saveErrorCommand(command, "process instance is null");
return null;
}else if(!checkThreadNum(command, validThreadNum)){
logger.info("there is not enough thread for this command: {}",command.toString() );
@ -153,11 +157,18 @@ public class ProcessDao extends AbstractBaseDao {
}
}catch (Exception e){
logger.error("scan command error ", e);
saveErrorCommand(command, e.toString());
delCommandByid(command.getId());
}
return null;
}
private void saveErrorCommand(Command command, String message) {
ErrorCommand errorCommand = new ErrorCommand(command, message);
this.errorCommandMapper.insert(errorCommand);
}
/**
* set process waiting thread
* @param command

88
escheduler-dao/src/main/java/cn/escheduler/dao/mapper/AccessTokenMapper.java

@ -0,0 +1,88 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.escheduler.dao.mapper;
import cn.escheduler.common.enums.UserType;
import cn.escheduler.dao.model.AccessToken;
import cn.escheduler.dao.model.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.type.EnumOrdinalTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.Timestamp;
import java.util.List;
public interface AccessTokenMapper {
/**
* insert accessToken
* @param accessToken
* @return
*/
@InsertProvider(type = AccessTokenMapperProvider.class, method = "insert")
@Options(useGeneratedKeys = true,keyProperty = "accessToken.id")
@SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty = "accessToken.id", before = false, resultType = int.class)
int insert(@Param("accessToken") AccessToken accessToken);
/**
* delete accessToken
* @param accessTokenId
* @return
*/
@DeleteProvider(type = AccessTokenMapperProvider.class, method = "delete")
int delete(@Param("accessTokenId") int accessTokenId);
/**
* update accessToken
*
* @param accessToken
* @return
*/
@UpdateProvider(type = AccessTokenMapperProvider.class, method = "update")
int update(@Param("accessToken") AccessToken accessToken);
/**
* query access token list paging
* @param searchVal
* @param offset
* @param pageSize
* @return
*/
@Results(value = {@Result(property = "id", column = "id", id = true, javaType = Integer.class, jdbcType = JdbcType.INTEGER),
@Result(property = "userId", column = "user_id", javaType = Integer.class, jdbcType = JdbcType.INTEGER),
@Result(property = "token", column = "token", javaType = String.class, jdbcType = JdbcType.VARCHAR),
@Result(property = "userName", column = "user_name", javaType = String.class, jdbcType = JdbcType.VARCHAR),
@Result(property = "expireTime", column = "expire_time", javaType = Timestamp.class, jdbcType = JdbcType.DATE),
@Result(property = "createTime", column = "create_time", javaType = Timestamp.class, jdbcType = JdbcType.DATE),
@Result(property = "updateTime", column = "update_time", javaType = Timestamp.class, jdbcType = JdbcType.DATE)
})
@SelectProvider(type = AccessTokenMapperProvider.class, method = "queryAccessTokenPaging")
List<AccessToken> queryAccessTokenPaging(@Param("searchVal") String searchVal,
@Param("offset") Integer offset,
@Param("pageSize") Integer pageSize);
/**
* count access token by search value
* @param searchVal
* @return
*/
@SelectProvider(type = AccessTokenMapperProvider.class, method = "countAccessTokenPaging")
Integer countAccessTokenPaging(@Param("searchVal") String searchVal);
}

130
escheduler-dao/src/main/java/cn/escheduler/dao/mapper/AccessTokenMapperProvider.java

@ -0,0 +1,130 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.escheduler.dao.mapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.jdbc.SQL;
import java.util.Map;
/**
* access token mapper provider
*
*/
public class AccessTokenMapperProvider {
private static final String TABLE_NAME = "t_escheduler_access_token";
/**
* insert accessToken
*
* @param parameter
* @return
*/
public String insert(Map<String, Object> parameter) {
return new SQL() {
{
INSERT_INTO(TABLE_NAME);
VALUES("`user_id`", "#{accessToken.userId}");
VALUES("`token`", "#{accessToken.token}");
VALUES("`expire_time`", "#{accessToken.expireTime}");;
VALUES("`create_time`", "#{accessToken.createTime}");
VALUES("`update_time`", "#{accessToken.updateTime}");
}
}.toString();
}
/**
* delete accessToken
*
* @param parameter
* @return
*/
public String delete(Map<String, Object> parameter) {
return new SQL() {
{
DELETE_FROM(TABLE_NAME);
WHERE("`id`=#{accessTokenId}");
}
}.toString();
}
/**
* update accessToken
*
* @param parameter
* @return
*/
public String update(Map<String, Object> parameter) {
return new SQL() {
{
UPDATE(TABLE_NAME);
SET("`user_id`=#{accessToken.userId}");
SET("`token`=#{accessToken.token}");
SET("`expire_time`=#{accessToken.expireTime}");
SET("`update_time`=#{accessToken.updateTime}");
WHERE("`id`=#{user.id}");
}
}.toString();
}
/**
* count user number by search value
* @param parameter
* @return
*/
public String countAccessTokenPaging(Map<String, Object> parameter) {
return new SQL() {{
SELECT("count(0)");
FROM(TABLE_NAME + " t,t_escheduler_user u");
Object searchVal = parameter.get("searchVal");
WHERE("u.id = t.user_id");
if(searchVal != null && StringUtils.isNotEmpty(searchVal.toString())){
WHERE(" u.user_name like concat('%', #{searchVal}, '%')");
}
}}.toString();
}
/**
* query user list paging
* @param parameter
* @return
*/
public String queryAccessTokenPaging(Map<String, Object> parameter) {
return new SQL() {
{
SELECT("t.*,u.user_name");
FROM(TABLE_NAME + " t,t_escheduler_user u");
Object searchVal = parameter.get("searchVal");
WHERE("u.id = t.user_id");
if(searchVal != null && StringUtils.isNotEmpty(searchVal.toString())){
WHERE(" u.user_name like concat('%', #{searchVal}, '%') ");
}
ORDER_BY(" t.update_time desc limit #{offset},#{pageSize} ");
}
}.toString();
}
}

45
escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ErrorCommandMapper.java

@ -0,0 +1,45 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.escheduler.dao.mapper;
import cn.escheduler.common.enums.*;
import cn.escheduler.dao.model.Command;
import cn.escheduler.dao.model.ErrorCommand;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.type.EnumOrdinalTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.Timestamp;
import java.util.List;
/**
* command mapper
*/
public interface ErrorCommandMapper {
/**
* inert error command
* @param errorCommand
* @return
*/
@InsertProvider(type = ErrorCommandMapperProvider.class, method = "insert")
@Options(useGeneratedKeys = true,keyProperty = "errorCommand.id")
@SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty = "errorCommand.id", before = false, resultType = int.class)
int insert(@Param("errorCommand") ErrorCommand errorCommand);
}

41
escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ErrorCommandMapperProvider.java

@ -0,0 +1,41 @@
package cn.escheduler.dao.mapper;
import cn.escheduler.common.enums.*;
import cn.escheduler.common.utils.EnumFieldUtil;
import org.apache.ibatis.jdbc.SQL;
import java.util.Map;
public class ErrorCommandMapperProvider {
private static final String TABLE_NAME = "t_escheduler_error_command";
/**
* inert command
*
* @param parameter
* @return
*/
public String insert(Map<String, Object> parameter) {
return new SQL() {
{
INSERT_INTO(TABLE_NAME);
VALUES("`command_type`", EnumFieldUtil.genFieldStr("errorCommand.commandType", CommandType.class));
VALUES("`process_definition_id`", "#{errorCommand.processDefinitionId}");
VALUES("`executor_id`", "#{errorCommand.executorId}");
VALUES("`command_param`", "#{errorCommand.commandParam}");
VALUES("`task_depend_type`", EnumFieldUtil.genFieldStr("errorCommand.taskDependType", TaskDependType.class));
VALUES("`failure_strategy`", EnumFieldUtil.genFieldStr("errorCommand.failureStrategy", FailureStrategy.class));
VALUES("`warning_type`", EnumFieldUtil.genFieldStr("errorCommand.warningType", WarningType.class));
VALUES("`process_instance_priority`", EnumFieldUtil.genFieldStr("errorCommand.processInstancePriority", Priority.class));
VALUES("`warning_group_id`", "#{errorCommand.warningGroupId}");
VALUES("`schedule_time`", "#{errorCommand.scheduleTime}");
VALUES("`update_time`", "#{errorCommand.updateTime}");
VALUES("`start_time`", "#{errorCommand.startTime}");
VALUES("`message`", "#{errorCommand.message}");
}
}.toString();
}
}

20
escheduler-dao/src/main/java/cn/escheduler/dao/mapper/UserMapper.java

@ -231,4 +231,24 @@ public interface UserMapper {
*/
@SelectProvider(type = UserMapperProvider.class, method = "queryQueueByProcessInstanceId")
String queryQueueByProcessInstanceId(@Param("processInstanceId") int processInstanceId);
/**
* query user by token
* @param token
* @return
*/
@Results(value = {
@Result(property = "id", column = "id", id = true, javaType = Integer.class, jdbcType = JdbcType.INTEGER),
@Result(property = "userName", column = "user_name", javaType = String.class, jdbcType = JdbcType.VARCHAR),
@Result(property = "userPassword", column = "user_password", javaType = String.class, jdbcType = JdbcType.VARCHAR),
@Result(property = "email", column = "email", javaType = String.class, jdbcType = JdbcType.VARCHAR),
@Result(property = "phone", column = "phone", javaType = String.class, jdbcType = JdbcType.VARCHAR),
@Result(property = "userType", column = "user_type", typeHandler = EnumOrdinalTypeHandler.class, javaType = UserType.class, jdbcType = JdbcType.TINYINT),
@Result(property = "tenantId", column = "tenant_id", javaType = Integer.class, jdbcType = JdbcType.INTEGER),
@Result(property = "createTime", column = "create_time", javaType = Timestamp.class, jdbcType = JdbcType.DATE),
@Result(property = "updateTime", column = "update_time", javaType = Timestamp.class, jdbcType = JdbcType.DATE)
})
@SelectProvider(type = UserMapperProvider.class, method = "queryUserByToken")
User queryUserByToken(@Param("token") String token);
}

16
escheduler-dao/src/main/java/cn/escheduler/dao/mapper/UserMapperProvider.java

@ -265,4 +265,20 @@ public class UserMapperProvider {
}.toString();
}
/**
* query user by id
* @param parameter
* @return
*/
public String queryUserByToken(Map<String, Object> parameter) {
return new SQL() {
{
SELECT("u.*");
FROM(TABLE_NAME + " u ,t_escheduler_access_token t");
WHERE(" u.id = t.user_id and token=#{token}");
}
}.toString();
}
}

126
escheduler-dao/src/main/java/cn/escheduler/dao/model/AccessToken.java

@ -0,0 +1,126 @@
package cn.escheduler.dao.model;
import java.util.Date;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class AccessToken {
/**
* id
*/
private int id;
/**
* user id
*/
private int userId;
/**
* user name
*/
private String userName;
/**
* user token
*/
private String token;
/**
* token expire time
*/
private Date expireTime;
/**
* create time
*/
private Date createTime;
/**
* update time
*/
private Date updateTime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public Date getExpireTime() {
return expireTime;
}
public void setExpireTime(Date expireTime) {
this.expireTime = expireTime;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Override
public String toString() {
return "AccessToken{" +
"id=" + id +
", userId=" + userId +
", userName='" + userName + '\'' +
", token='" + token + '\'' +
", expireTime=" + expireTime +
", createTime=" + createTime +
", updateTime=" + updateTime +
'}';
}
}

275
escheduler-dao/src/main/java/cn/escheduler/dao/model/ErrorCommand.java

@ -0,0 +1,275 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.escheduler.dao.model;
import cn.escheduler.common.enums.*;
import java.util.Date;
/**
* command
*/
public class ErrorCommand {
/**
* id
*/
private int id;
/**
* command type
*/
private CommandType commandType;
/**
* process definition id
*/
private int processDefinitionId;
/**
* executor id
*/
private int executorId;
/**
* command parameter, format json
*/
private String commandParam;
/**
* task depend type
*/
private TaskDependType taskDependType;
/**
* failure strategy
*/
private FailureStrategy failureStrategy;
/**
* warning type
*/
private WarningType warningType;
/**
* warning group id
*/
private Integer warningGroupId;
/**
* schedule time
*/
private Date scheduleTime;
/**
* start time
*/
private Date startTime;
/**
* process instance priority
*/
private Priority processInstancePriority;
/**
* update time
*/
private Date updateTime;
/**
* 执行信息
*/
private String message;
public ErrorCommand(Command command, String message){
this.commandType = command.getCommandType();
this.executorId = command.getExecutorId();
this.processDefinitionId = command.getProcessDefinitionId();
this.commandParam = command.getCommandParam();
this.warningType = command.getWarningType();
this.warningGroupId = command.getWarningGroupId();
this.scheduleTime = command.getScheduleTime();
this.taskDependType = command.getTaskDependType();
this.failureStrategy = command.getFailureStrategy();
this.startTime = command.getStartTime();
this.updateTime = command.getUpdateTime();
this.processInstancePriority = command.getProcessInstancePriority();
this.message = message;
}
public ErrorCommand(
CommandType commandType,
TaskDependType taskDependType,
FailureStrategy failureStrategy,
int executorId,
int processDefinitionId,
String commandParam,
WarningType warningType,
int warningGroupId,
Date scheduleTime,
Priority processInstancePriority,
String message){
this.commandType = commandType;
this.executorId = executorId;
this.processDefinitionId = processDefinitionId;
this.commandParam = commandParam;
this.warningType = warningType;
this.warningGroupId = warningGroupId;
this.scheduleTime = scheduleTime;
this.taskDependType = taskDependType;
this.failureStrategy = failureStrategy;
this.startTime = new Date();
this.updateTime = new Date();
this.processInstancePriority = processInstancePriority;
this.message = message;
}
public TaskDependType getTaskDependType() {
return taskDependType;
}
public void setTaskDependType(TaskDependType taskDependType) {
this.taskDependType = taskDependType;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public CommandType getCommandType() {
return commandType;
}
public void setCommandType(CommandType commandType) {
this.commandType = commandType;
}
public int getProcessDefinitionId() {
return processDefinitionId;
}
public void setProcessDefinitionId(int processDefinitionId) {
this.processDefinitionId = processDefinitionId;
}
public FailureStrategy getFailureStrategy() {
return failureStrategy;
}
public void setFailureStrategy(FailureStrategy failureStrategy) {
this.failureStrategy = failureStrategy;
}
public void setCommandParam(String commandParam) {
this.commandParam = commandParam;
}
public String getCommandParam() {
return commandParam;
}
public WarningType getWarningType() {
return warningType;
}
public void setWarningType(WarningType warningType) {
this.warningType = warningType;
}
public Integer getWarningGroupId() {
return warningGroupId;
}
public void setWarningGroupId(Integer warningGroupId) {
this.warningGroupId = warningGroupId;
}
public Date getScheduleTime() {
return scheduleTime;
}
public void setScheduleTime(Date scheduleTime) {
this.scheduleTime = scheduleTime;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public int getExecutorId() {
return executorId;
}
public void setExecutorId(int executorId) {
this.executorId = executorId;
}
public Priority getProcessInstancePriority() {
return processInstancePriority;
}
public void setProcessInstancePriority(Priority processInstancePriority) {
this.processInstancePriority = processInstancePriority;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
@Override
public String toString() {
return "Command{" +
"id=" + id +
", commandType=" + commandType +
", processDefinitionId=" + processDefinitionId +
", executorId=" + executorId +
", commandParam='" + commandParam + '\'' +
", taskDependType=" + taskDependType +
", failureStrategy=" + failureStrategy +
", warningType=" + warningType +
", warningGroupId=" + warningGroupId +
", scheduleTime=" + scheduleTime +
", startTime=" + startTime +
", processInstancePriority=" + processInstancePriority +
", updateTime=" + updateTime +
", message=" + message +
'}';
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

62
escheduler-dao/src/test/java/cn/escheduler/dao/mapper/AccessTokenMapperTest.java

@ -0,0 +1,62 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.escheduler.dao.mapper;
import cn.escheduler.common.utils.EncryptionUtils;
import cn.escheduler.dao.datasource.ConnectionFactory;
import cn.escheduler.dao.model.AccessToken;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.util.Date;
import java.util.List;
public class AccessTokenMapperTest {
AccessTokenMapper accessTokenMapper;
@Before
public void before(){
accessTokenMapper = ConnectionFactory.getSqlSession().getMapper(AccessTokenMapper.class);
}
@Test
public void testInsert(){
AccessToken accessToken = new AccessToken();
accessToken.setUserId(10);
accessToken.setExpireTime(new Date());
accessToken.setToken("ssssssssssssssssssssssssss");
accessToken.setCreateTime(new Date());
accessToken.setUpdateTime(new Date());
accessTokenMapper.insert(accessToken);
}
@Test
public void testListPaging(){
Integer count = accessTokenMapper.countAccessTokenPaging("");
Assert.assertEquals(count, (Integer) 5);
List<AccessToken> accessTokenList = accessTokenMapper.queryAccessTokenPaging("", 0, 2);
Assert.assertEquals(accessTokenList.size(), 5);
}
}

6
escheduler-dao/src/test/java/cn/escheduler/dao/mapper/UserMapperTest.java

@ -66,4 +66,10 @@ public class UserMapperTest {
Assert.assertEquals(queue, "ait");
}
@Test
public void testQueryUserByToken(){
User user = userMapper.queryUserByToken("ad9e8fccfc11bd18bb45aa994568b8ef");
Assert.assertEquals(user.getUserName(), "qiaozhanwei");
}
}

2
escheduler-rpc/pom.xml

@ -4,7 +4,7 @@
<parent>
<artifactId>escheduler</artifactId>
<groupId>cn.analysys</groupId>
<version>1.0.0-SNAPSHOT</version>
<version>1.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

2
escheduler-server/pom.xml

@ -3,7 +3,7 @@
<parent>
<artifactId>escheduler</artifactId>
<groupId>cn.analysys</groupId>
<version>1.0.0-SNAPSHOT</version>
<version>1.0.1-SNAPSHOT</version>
</parent>
<artifactId>escheduler-server</artifactId>
<name>escheduler-server</name>

2
escheduler-server/src/main/java/cn/escheduler/server/worker/runner/FetchTaskThread.java

@ -172,7 +172,7 @@ public class FetchTaskThread implements Runnable{
FileUtils.createWorkDirAndUserIfAbsent(execLocalPath,
processInstance.getTenantCode(), logger);
logger.info("task : {} ready to submit to task scheduler thread",taskId);
// submit task
workerExecService.submit(new TaskScheduleThread(taskInstance, processDao));
}

73
escheduler-server/src/main/java/cn/escheduler/server/worker/task/PythonCommandExecutor.java

@ -16,12 +16,13 @@
*/
package cn.escheduler.server.worker.task;
import cn.escheduler.common.Constants;
import cn.escheduler.common.utils.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
@ -34,6 +35,8 @@ import java.util.function.Consumer;
*/
public class PythonCommandExecutor extends AbstractCommandExecutor {
private static final Logger logger = LoggerFactory.getLogger(PythonCommandExecutor.class);
public static final String PYTHON = "python";
@ -63,27 +66,13 @@ public class PythonCommandExecutor extends AbstractCommandExecutor {
*/
@Override
protected void createCommandFileIfNotExists(String execCommand, String commandFile) throws IOException {
logger.info("proxy user:{}, work dir:{}", tenantCode, taskDir);
logger.info("tenant :{}, work dir:{}", tenantCode, taskDir);
if (!Files.exists(Paths.get(commandFile))) {
logger.info("generate command file:{}", commandFile);
StringBuilder sb = new StringBuilder(200);
sb.append("#-*- encoding=utf8 -*-\n");
sb.append("import os,sys\n");
sb.append("BASEDIR = os.path.dirname(os.path.realpath(__file__))\n");
sb.append("os.chdir(BASEDIR)\n");
if (StringUtils.isNotEmpty(envFile)) {
String[] envArray = envFile.split("\\.");
if(envArray.length == 2){
String path = envArray[0];
logger.info("path:"+path);
int index = path.lastIndexOf("/");
sb.append(String.format("sys.path.append('%s')\n",path.substring(0,index)));
sb.append(String.format("import %s\n",path.substring(index+1)));
}
}
sb.append("\n\n");
sb.append(String.format("import py_%s_node\n",taskAppId));
@ -96,7 +85,14 @@ public class PythonCommandExecutor extends AbstractCommandExecutor {
@Override
protected String commandType() {
return PYTHON;
String envPath = System.getProperty("user.dir") + Constants.SINGLE_SLASH + "conf"+
Constants.SINGLE_SLASH +"env" + Constants.SINGLE_SLASH + Constants.ESCHEDULER_ENV_SH;
String pythonHome = getPythonHome(envPath);
if (StringUtils.isEmpty(pythonHome)){
return PYTHON;
}
return pythonHome;
}
@Override
@ -109,4 +105,45 @@ public class PythonCommandExecutor extends AbstractCommandExecutor {
return true;
}
/**
* get python home
* @param envPath
* @return
*/
private static String getPythonHome(String envPath){
BufferedReader br = null;
String line = null;
StringBuilder sb = new StringBuilder();
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(envPath)));
while ((line = br.readLine()) != null){
if (line.contains(Constants.PYTHON_HOME)){
sb.append(line);
break;
}
}
String result = sb.toString();
if (org.apache.commons.lang.StringUtils.isEmpty(result)){
return null;
}
String[] arrs = result.split("=");
if (arrs.length == 2){
return arrs[1];
}
}catch (IOException e){
logger.error("read file failed : " + e.getMessage(),e);
}finally {
try {
if (br != null){
br.close();
}
} catch (IOException e) {
logger.error(e.getMessage(),e);
}
}
return null;
}
}

2
escheduler-server/src/main/java/cn/escheduler/server/worker/task/python/PythonTask.java

@ -72,7 +72,7 @@ public class PythonTask extends AbstractTask {
this.pythonProcessTask = new PythonCommandExecutor(this::logHandle,
taskProps.getTaskDir(), taskProps.getTaskAppId(),
taskProps.getTenantCode(), CommonUtils.getPythonSystemEnvPath(), taskProps.getTaskStartTime(),
taskProps.getTenantCode(), null, taskProps.getTaskStartTime(),
taskProps.getTaskTimeout(), logger);
this.processDao = DaoFactory.getDaoInstance(ProcessDao.class);
}

65
escheduler-server/src/test/java/cn/escheduler/server/worker/EnvFileTest.java

@ -0,0 +1,65 @@
package cn.escheduler.server.worker;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* Created by qiaozhanwei on 2019/4/15.
*/
public class EnvFileTest {
private static final Logger logger = LoggerFactory.getLogger(EnvFileTest.class);
public static void main(String[] args) {
String path = System.getProperty("user.dir")+"\\script\\env\\.escheduler_env.sh";
String pythonHome = getPythonHome(path);
logger.info(pythonHome);
}
/**
* get python home
* @param path
* @return
*/
private static String getPythonHome(String path){
BufferedReader br = null;
String line = null;
StringBuilder sb = new StringBuilder();
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
while ((line = br.readLine()) != null){
if (line.contains("PYTHON_HOME")){
sb.append(line);
break;
}
}
String result = sb.toString();
if (StringUtils.isEmpty(result)){
return null;
}
String[] arrs = result.split("=");
if (arrs.length == 2){
return arrs[1];
}
}catch (IOException e){
logger.error("read file failed : " + e.getMessage(),e);
}finally {
try {
if (br != null){
br.close();
}
} catch (IOException e) {
logger.error(e.getMessage(),e);
}
}
return null;
}
}

87
escheduler-ui/build/i18n.js

@ -1,87 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const fs = require('fs');
const path = require('path')
const glob = require('globby')
function moduleName (modules) {
let filename = path.basename(modules)
let parts = filename.split('.')
parts.pop()
filename = parts.join('.')
return path.dirname(modules) + '/' + filename
}
const jsEntry = () => {
const obj = {}
const files = glob.sync([
'./src/js/conf/login/**/*.vue',
'./src/js/conf/login/**/*.js',
'./src/js/conf/home/**/**/**/**/**/**/**/**/*.vue',
'./src/js/conf/home/**/**/**/**/**/**/**/**/*.js',
'./src/js/module/**/**/**/**/**/*.vue',
'./src/js/module/**/**/**/**/**/*.js'
])
files.forEach(val => {
let parts = val.split(/[\\/]/)
parts.shift()
parts.shift()
let modules = parts.join('/')
let entry = moduleName(modules)
obj[entry] = val
})
return obj
}
/* eslint-disable */
let reg = /\$t\([\w,""''~\-\s.?!\+\/<>()\u4e00-\u9fa5]*\)/g
let map = {}
let entryPathList = ''
let matchPathList = ''
let jsEntryObj = jsEntry()
for (let i in jsEntryObj) {
entryPathList += jsEntryObj[i] + '\n'
let data = fs.readFileSync(path.join(jsEntryObj[i]), 'utf-8')
if (reg.test(data)) {
matchPathList += jsEntryObj[i] + '\n'
let str = data.replace(/[""'']/g, '')
str.replace(reg, function () {
if (arguments && arguments[0]) {
let key = arguments[0]
key = key.substring(3, key.length - 1)
map[key] = key
}
})
}
}
let outPath = path.join(__dirname, '../src/js/module/i18n/locale/zh_CN.js')
fs.unlink(outPath, (err) => {
if (err) {
console.error('删除zh_CN.js文件出错 -- \n', err)
} else {
console.log('删除zh_CN.js文件成功')
}
})
fs.writeFile(outPath, 'export default ' + JSON.stringify(map, null, 2), function (err) {
if (err) {
console.error('写入zh_CN.js文件出错 -- \n', err)
} else {
console.log('写入zh_CN.js文件成功')
}
})

40
escheduler-ui/src/js/conf/home/pages/monitor/index.vue

@ -0,0 +1,40 @@
<template>
<div class="index-model">
index
</div>
</template>
<script>
export default {
name: 'monitor-index',
data () {
return {}
},
props: {},
methods: {},
watch: {},
beforeCreate () {
},
created () {
},
beforeMount () {
},
mounted () {
},
beforeUpdate () {
},
updated () {
},
beforeDestroy () {
},
destroyed () {
},
computed: {},
components: {}
}
</script>
<style lang="scss" rel="stylesheet/scss">
.index-model {
}
</style>

19
escheduler-ui/src/js/conf/home/pages/projects/index.vue

@ -1,9 +1,24 @@
<template>
<router-view></router-view>
<div class="main-layout-box" :class="!isProjectsList ? '' : 'no'">
<m-secondary-menu :type="'projects'" v-if="!isProjectsList"></m-secondary-menu>
<router-view></router-view>
</div>
</template>
<script>
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
export default {
name: 'projects-index'
name: 'projects-index',
data () {
return {
isProjectsList: this.$router.history.current.name === 'projects-list'
}
},
watch: {
'$route' ({ name }) {
this.isProjectsList = name === 'projects-list'
}
},
components: { mSecondaryMenu }
}
</script>

35
escheduler-ui/src/js/conf/home/pages/projects/pages/_source/taskRecordList/index.vue

@ -1,25 +1,22 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'projects'"></m-secondary-menu>
<m-list-construction :title="config.title">
<template slot="conditions">
<m-conditions @on-query="_onQuery"></m-conditions>
<m-list-construction :title="config.title">
<template slot="conditions">
<m-conditions @on-query="_onQuery"></m-conditions>
</template>
<template slot="content">
<template v-if="taskRecordList.length">
<m-list :task-record-list="taskRecordList" @on-update="_onUpdate" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize">
</m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template slot="content">
<template v-if="taskRecordList.length">
<m-list :task-record-list="taskRecordList" @on-update="_onUpdate" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize">
</m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!taskRecordList.length">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading"></m-spin>
<template v-if="!taskRecordList.length">
<m-no-data></m-no-data>
</template>
</m-list-construction>
</div>
<m-spin :is-spin="isLoading"></m-spin>
</template>
</m-list-construction>
</template>
<script>
import _ from 'lodash'

5
escheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/create/index.vue

@ -1,8 +1,5 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'projects'"></m-secondary-menu>
<m-create-dag></m-create-dag>
</div>
<m-create-dag></m-create-dag>
</template>
<script>
import mCreateDag from '@/conf/home/pages/dag/index'

5
escheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/details/index.vue

@ -1,8 +1,5 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'projects'"></m-secondary-menu>
<m-definition-details></m-definition-details>
</div>
<m-definition-details></m-definition-details>
</template>
<script>
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'

2
escheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/email.vue

@ -45,7 +45,7 @@
<script>
import _ from 'lodash'
import i18n from '@/module/i18n'
import emailList from '~/localData/email'
import emailList from '~/external/email'
import { isEmial, fuzzyQuery } from './util'
export default {

41
escheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/index.vue

@ -1,28 +1,25 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'projects'"></m-secondary-menu>
<m-list-construction :title="$t('Process definition')">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group">
<x-button type="ghost" size="small" v-ps="['GENERAL_USER']" @click="() => this.$router.push({name: 'definition-create'})">{{$t('Create process')}}</x-button>
</template>
</m-conditions>
</template>
<template slot="content">
<template v-if="processListP.length">
<m-list :process-list="processListP" @on-update="_onUpdate" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize"></m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!processListP.length">
<m-no-data></m-no-data>
<m-list-construction :title="$t('Process definition')">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group">
<x-button type="ghost" size="small" v-ps="['GENERAL_USER']" @click="() => this.$router.push({name: 'definition-create'})">{{$t('Create process')}}</x-button>
</template>
<m-spin :is-spin="isLoading"></m-spin>
</m-conditions>
</template>
<template slot="content">
<template v-if="processListP.length">
<m-list :process-list="processListP" @on-update="_onUpdate" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize"></m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!processListP.length">
<m-no-data></m-no-data>
</template>
</m-list-construction>
</div>
<m-spin :is-spin="isLoading"></m-spin>
</template>
</m-list-construction>
</template>
<script>
import _ from 'lodash'

99
escheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/tree/index.vue

@ -1,59 +1,56 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'projects'"></m-secondary-menu>
<m-list-construction :title="$t('TreeView')">
<template slot="conditions"></template>
<template slot="content">
<div class="tree-view-index-model">
<div class="tree-limit-select">
<x-select v-model="limit" style="width: 70px;" @on-change="_onChangeSelect">
<x-option
v-for="city in [{value:25},{value:50},{value:75},{value:100}]"
:key="city.value"
:value="city.value"
:label="city.value">
</x-option>
</x-select>
<x-button
@click="_rtTasksDag"
v-if="$route.query.subProcessIds"
type="primary"
size="default"
icon="fa fa-reply">
{{$t('Return_1')}}
</x-button>
<m-list-construction :title="$t('TreeView')">
<template slot="conditions"></template>
<template slot="content">
<div class="tree-view-index-model">
<div class="tree-limit-select">
<x-select v-model="limit" style="width: 70px;" @on-change="_onChangeSelect">
<x-option
v-for="city in [{value:25},{value:50},{value:75},{value:100}]"
:key="city.value"
:value="city.value"
:label="city.value">
</x-option>
</x-select>
<x-button
@click="_rtTasksDag"
v-if="$route.query.subProcessIds"
type="primary"
size="default"
icon="fa fa-reply">
{{$t('Return_1')}}
</x-button>
</div>
<div class="tasks-color">
<div class="toolbar-color-sp">
<a href="javascript:">
<span>Node Type</span>
</a>
<a href="javascript:" v-for="(k,v) in tasksType">
<i class="fa fa-circle" :style="{color:k.color}"></i>
<span>{{v}}</span>
</a>
</div>
<div class="tasks-color">
<div class="toolbar-color-sp">
<a href="javascript:">
<span>Node Type</span>
</a>
<a href="javascript:" v-for="(k,v) in tasksType">
<i class="fa fa-circle" :style="{color:k.color}"></i>
<span>{{v}}</span>
</a>
</div>
<div class="state-tasks-color-sp">
<a href="javascript:">
<span>{{$t('Task Status')}}</span>
</a>
<a href="javascript:" v-for="(item) in tasksState">
<i class="fa fa-square" :style="{color:item.color}"></i>
<span>{{item.desc}}</span>
</a>
</div>
<div class="state-tasks-color-sp">
<a href="javascript:">
<span>{{$t('Task Status')}}</span>
</a>
<a href="javascript:" v-for="(item) in tasksState">
<i class="fa fa-square" :style="{color:item.color}"></i>
<span>{{item.desc}}</span>
</a>
</div>
<div class="tree-model" v-show="!isNodata">
<div class="d3-tree">
<svg class='tree' width="100%"></svg>
</div>
</div>
<div class="tree-model" v-show="!isNodata">
<div class="d3-tree">
<svg class='tree' width="100%"></svg>
</div>
<m-no-data v-if="isNodata"></m-no-data>
</div>
<m-spin :is-spin="isLoading"></m-spin>
</template>
</m-list-construction>
</div>
<m-no-data v-if="isNodata"></m-no-data>
</div>
<m-spin :is-spin="isLoading"></m-spin>
</template>
</m-list-construction>
</template>
<script>

13
escheduler-ui/src/js/conf/home/pages/projects/pages/definition/timing/index.vue

@ -1,12 +1,9 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'projects'"></m-secondary-menu>
<m-list-construction :title="$t('Cron Manage')">
<template slot="content">
<m-list></m-list>
</template>
</m-list-construction>
</div>
<m-list-construction :title="$t('Cron Manage')">
<template slot="content">
<m-list></m-list>
</template>
</m-list-construction>
</template>
<script>
import mList from './_source/list'

27
escheduler-ui/src/js/conf/home/pages/projects/pages/index/index.vue

@ -1,12 +1,9 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'projects'"></m-secondary-menu>
<m-list-construction :title="$t('Project Home')">
<template slot="content">
<m-project-chart :id="id"></m-project-chart>
</template>
</m-list-construction>
</div>
<m-list-construction :title="$t('Project Home')">
<template slot="content">
<m-project-chart :id="id"></m-project-chart>
</template>
</m-list-construction>
</template>
<script>
import mProjectChart from './_source/projectChart'
@ -21,20 +18,6 @@
id: localStore.getItem('projectId') || null
}
},
props: {},
methods: {
},
watch: {},
created () {
},
mounted () {
},
components: { mSecondaryMenu, mListConstruction, mProjectChart }
}
</script>
<style lang="scss" rel="stylesheet/scss">
</style>

24
escheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/details/index.vue

@ -1,8 +1,5 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'projects'"></m-secondary-menu>
<m-instance-details></m-instance-details>
</div>
<m-instance-details></m-instance-details>
</template>
<script>
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
@ -12,23 +9,6 @@
data () {
return {}
},
props: {},
methods: {},
watch: {},
created () {
},
mounted () {
},
updated () {
},
beforeDestroy () {
},
destroyed () {
},
computed: {},
components: { mInstanceDetails, mSecondaryMenu }
}
</script>
<style lang="scss" rel="stylesheet/scss">
</style>
</script>

49
escheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/gantt/index.vue

@ -1,32 +1,29 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'projects'"></m-secondary-menu>
<m-list-construction :title="$t('Gantt')">
<template slot="content">
<div class="gantt-model">
<div class="gantt-state">
<div class="state-tasks-color-sp">
<a href="javascript:">
<span>{{$t('Task Status')}}</span>
</a>
<a href="javascript:" v-for="(item) in tasksState">
<i class="fa fa-square" :style="{color:item.color}"></i>
<span>{{item.desc}}</span>
</a>
</div>
<m-list-construction :title="$t('Gantt')">
<template slot="content">
<div class="gantt-model">
<div class="gantt-state">
<div class="state-tasks-color-sp">
<a href="javascript:">
<span>{{$t('Task Status')}}</span>
</a>
<a href="javascript:" v-for="(item) in tasksState">
<i class="fa fa-square" :style="{color:item.color}"></i>
<span>{{item.desc}}</span>
</a>
</div>
<template v-show="!isNodata">
<div class="gantt"></div>
</template>
<template v-if="isNodata">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading">
</m-spin>
</div>
</template>
</m-list-construction>
</div>
<template v-show="!isNodata">
<div class="gantt"></div>
</template>
<template v-if="isNodata">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading">
</m-spin>
</div>
</template>
</m-list-construction>
</template>
<script>
import { mapActions } from 'vuex'

35
escheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/list/index.vue

@ -1,25 +1,22 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'projects'"></m-secondary-menu>
<m-list-construction :title="$t('Process Instance')">
<template slot="conditions">
<m-instance-conditions @on-query="_onQuery"></m-instance-conditions>
<m-list-construction :title="$t('Process Instance')">
<template slot="conditions">
<m-instance-conditions @on-query="_onQuery"></m-instance-conditions>
</template>
<template slot="content">
<template v-if="processInstanceList.length">
<m-list :process-instance-list="processInstanceList" @on-update="_onUpdate" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize">
</m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template slot="content">
<template v-if="processInstanceList.length">
<m-list :process-instance-list="processInstanceList" @on-update="_onUpdate" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize">
</m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!processInstanceList.length">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading"></m-spin>
<template v-if="!processInstanceList.length">
<m-no-data></m-no-data>
</template>
</m-list-construction>
</div>
<m-spin :is-spin="isLoading"></m-spin>
</template>
</m-list-construction>
</template>
<script>
import _ from 'lodash'

35
escheduler-ui/src/js/conf/home/pages/projects/pages/taskInstance/index.vue

@ -1,25 +1,22 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'projects'"></m-secondary-menu>
<m-list-construction :title="$t('Task Instance')">
<template slot="conditions">
<m-instance-conditions @on-query="_onQuery"></m-instance-conditions>
<m-list-construction :title="$t('Task Instance')">
<template slot="conditions">
<m-instance-conditions @on-query="_onQuery"></m-instance-conditions>
</template>
<template slot="content">
<template v-if="taskInstanceList.length">
<m-list :task-instance-list="taskInstanceList" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize">
</m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template slot="content">
<template v-if="taskInstanceList.length">
<m-list :task-instance-list="taskInstanceList" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize">
</m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!taskInstanceList.length">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading"></m-spin>
<template v-if="!taskInstanceList.length">
<m-no-data></m-no-data>
</template>
</m-list-construction>
</div>
<m-spin :is-spin="isLoading"></m-spin>
</template>
</m-list-construction>
</template>
<script>
import _ from 'lodash'

9
escheduler-ui/src/js/conf/home/pages/resource/index.vue

@ -1,8 +1,13 @@
<template>
<router-view></router-view>
<div class="main-layout-box">
<m-secondary-menu :type="'resource'"></m-secondary-menu>
<router-view></router-view>
</div>
</template>
<script>
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
export default {
name: 'resource-index'
name: 'resource-index',
components: { mSecondaryMenu }
}
</script>

122
escheduler-ui/src/js/conf/home/pages/resource/pages/file/pages/create/index.vue

@ -1,65 +1,62 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'resource'"></m-secondary-menu>
<m-list-construction :title="$t('Create File')">
<template slot="content">
<div class="resource-create-model">
<m-list-box-f>
<template slot="name"><b>*</b>{{$t('File Name')}}</template>
<template slot="content">
<x-input
type="input"
v-model="fileName"
style="width: 300px;"
:placeholder="$t('Please enter name')"
autocomplete="off">
</x-input>
</template>
</m-list-box-f>
<m-list-box-f>
<template slot="name"><b>*</b>{{$t('File Format')}}</template>
<template slot="content">
<x-select v-model="suffix" style="width: 100px;" @on-change="_onChange">
<x-option
v-for="city in fileTypeList"
:key="city"
:value="city"
:label="city">
</x-option>
</x-select>
</template>
</m-list-box-f>
<m-list-box-f>
<template slot="name">{{$t('Description')}}</template>
<template slot="content">
<x-input
type="textarea"
v-model="desc"
style="width: 430px;"
:placeholder="$t('Please enter description')"
autocomplete="off">
</x-input>
</template>
</m-list-box-f>
<m-list-box-f>
<template slot="name"><b>*</b>{{$t('File Content')}}</template>
<template slot="content">
<textarea id="code-create-mirror" name="code-create-mirror"></textarea>
</template>
</m-list-box-f>
<m-list-box-f>
<template slot="name">&nbsp;</template>
<template slot="content">
<div class="submit">
<x-button type="primary" shape="circle" :loading="spinnerLoading" @click="ok()" v-ps="['GENERAL_USER']">{{spinnerLoading ? 'Loading...' : $t('Create')}} </x-button>
<x-button type="text" @click="() => $router.push({name: 'file'})"> {{$t('Cancel')}} </x-button>
</div>
</template>
</m-list-box-f>
</div>
</template>
</m-list-construction>
</div>
<m-list-construction :title="$t('Create File')">
<template slot="content">
<div class="resource-create-model">
<m-list-box-f>
<template slot="name"><b>*</b>{{$t('File Name')}}</template>
<template slot="content">
<x-input
type="input"
v-model="fileName"
style="width: 300px;"
:placeholder="$t('Please enter name')"
autocomplete="off">
</x-input>
</template>
</m-list-box-f>
<m-list-box-f>
<template slot="name"><b>*</b>{{$t('File Format')}}</template>
<template slot="content">
<x-select v-model="suffix" style="width: 100px;" @on-change="_onChange">
<x-option
v-for="city in fileTypeList"
:key="city"
:value="city"
:label="city">
</x-option>
</x-select>
</template>
</m-list-box-f>
<m-list-box-f>
<template slot="name">{{$t('Description')}}</template>
<template slot="content">
<x-input
type="textarea"
v-model="desc"
style="width: 430px;"
:placeholder="$t('Please enter description')"
autocomplete="off">
</x-input>
</template>
</m-list-box-f>
<m-list-box-f>
<template slot="name"><b>*</b>{{$t('File Content')}}</template>
<template slot="content">
<textarea id="code-create-mirror" name="code-create-mirror"></textarea>
</template>
</m-list-box-f>
<m-list-box-f>
<template slot="name">&nbsp;</template>
<template slot="content">
<div class="submit">
<x-button type="primary" shape="circle" :loading="spinnerLoading" @click="ok()" v-ps="['GENERAL_USER']">{{spinnerLoading ? 'Loading...' : $t('Create')}} </x-button>
<x-button type="text" @click="() => $router.push({name: 'file'})"> {{$t('Cancel')}} </x-button>
</div>
</template>
</m-list-box-f>
</div>
</template>
</m-list-construction>
</template>
<script>
import i18n from '@/module/i18n'
@ -70,7 +67,6 @@
import mListBoxF from '@/module/components/listBoxF/listBoxF'
import mSpin from '@/module/components/spin/spin'
import mConditions from '@/module/components/conditions/conditions'
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
import mListConstruction from '@/module/components/listConstruction/listConstruction'
let editor
@ -158,7 +154,7 @@
editor.off($('.code-create-mirror'), 'keypress', this.keypress)
},
computed: {},
components: { mSecondaryMenu, mListConstruction, mConditions, mSpin, mListBoxF }
components: { mListConstruction, mConditions, mSpin, mListBoxF }
}
</script>

52
escheduler-ui/src/js/conf/home/pages/resource/pages/file/pages/details/index.vue

@ -1,34 +1,31 @@
<template>
<div class="main-layout-box file-details-model">
<m-secondary-menu :type="'resource'" ></m-secondary-menu>
<m-list-construction :title="$t('File Details')">
<div slot="content" style="margin: 20px">
<div class="file-details-content">
<h2>
<span>{{name}}</span>
<div class="down">
<i class="iconfont" data-container="body" data-toggle="tooltip" :title="$t('Download Details')" @click="_downloadFile">&#xe610;</i>
<em>{{size}}</em>
</div>
</h2>
<template v-if="isNoType">
<m-list-construction :title="$t('File Details')">
<div slot="content" style="margin: 20px">
<div class="file-details-content">
<h2>
<span>{{name}}</span>
<div class="down">
<i class="iconfont" data-container="body" data-toggle="tooltip" :title="$t('Download Details')" @click="_downloadFile">&#xe610;</i>
<em>{{size}}</em>
</div>
</h2>
<template v-if="isNoType">
<div class="code-mirror-model" v-if="!msg">
<textarea id="code-details-mirror" name="code-details-mirror"></textarea>
</div>
<div class="code-mirror-model" v-if="!msg">
<textarea id="code-details-mirror" name="code-details-mirror"></textarea>
</div>
<m-no-data :msg="msg" v-if="msg"></m-no-data>
<m-no-data :msg="msg" v-if="msg"></m-no-data>
</template>
<template v-if="!isNoType">
<m-no-type></m-no-type>
</template>
</div>
<m-spin :is-spin="isLoading">
</m-spin>
</template>
<template v-if="!isNoType">
<m-no-type></m-no-type>
</template>
</div>
</m-list-construction>
</div>
<m-spin :is-spin="isLoading">
</m-spin>
</div>
</m-list-construction>
</template>
<script>
import _ from 'lodash'
@ -42,7 +39,6 @@
import mSpin from '@/module/components/spin/spin'
import localStore from '@/module/util/localStorage'
import mNoData from '@/module/components/noData/noData'
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
import mListConstruction from '@/module/components/listConstruction/listConstruction'
let editor
@ -202,7 +198,7 @@
}
}
},
components: { mListConstruction, mNoType, mSpin, mSecondaryMenu, mNoData }
components: { mListConstruction, mNoType, mSpin, mNoData }
}
</script>

56
escheduler-ui/src/js/conf/home/pages/resource/pages/file/pages/edit/index.vue

@ -1,34 +1,31 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'resource'" ></m-secondary-menu>
<m-list-construction :title="$t('File Details')">
<div slot="content" style="margin: 20px">
<div class="file-edit-content">
<h2>
<span>{{name}}</span>
</h2>
<template v-show="isNoType">
<template v-if="!msg">
<div class="code-mirror-model">
<textarea id="code-edit-mirror" name="code-edit-mirror"></textarea>
</div>
<div class="submit-c">
<x-button type="text" shape="circle" @click="close()" :disabled="disabled"> {{$t('Return')}} </x-button>
<x-button type="primary" shape="circle" :loading="spinnerLoading" @click="ok()">{{spinnerLoading ? 'Loading...' : $t('Save')}} </x-button>
</div>
</template>
<m-no-data :msg="msg" v-if="msg"></m-no-data>
</template>
<template v-if="!isNoType">
<m-no-type></m-no-type>
<m-list-construction :title="$t('File Details')">
<div slot="content" style="margin: 20px">
<div class="file-edit-content">
<h2>
<span>{{name}}</span>
</h2>
<template v-show="isNoType">
<template v-if="!msg">
<div class="code-mirror-model">
<textarea id="code-edit-mirror" name="code-edit-mirror"></textarea>
</div>
<div class="submit-c">
<x-button type="text" shape="circle" @click="close()" :disabled="disabled"> {{$t('Return')}} </x-button>
<x-button type="primary" shape="circle" :loading="spinnerLoading" @click="ok()">{{spinnerLoading ? 'Loading...' : $t('Save')}} </x-button>
</div>
</template>
</div>
<m-spin :is-spin="isLoading">
</m-spin>
<m-no-data :msg="msg" v-if="msg"></m-no-data>
</template>
<template v-if="!isNoType">
<m-no-type></m-no-type>
</template>
</div>
</m-list-construction>
</div>
<m-spin :is-spin="isLoading">
</m-spin>
</div>
</m-list-construction>
</template>
<script>
import _ from 'lodash'
@ -41,7 +38,6 @@
import localStore from '@/module/util/localStorage'
import mNoData from '@/module/components/noData/noData'
import { handlerSuffix } from '../details/_source/utils'
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
import mListConstruction from '@/module/components/listConstruction/listConstruction'
let editor
@ -158,7 +154,7 @@
},
computed: {
},
components: { mListConstruction, mNoType, mSpin, mSecondaryMenu, mNoData }
components: { mListConstruction, mNoType, mSpin, mNoData }
}
</script>

54
escheduler-ui/src/js/conf/home/pages/resource/pages/file/pages/list/index.vue

@ -1,33 +1,30 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'resource'"></m-secondary-menu>
<m-list-construction :title="$t('File Manage')">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group">
<x-button-group size="small" >
<x-button type="ghost" @click="() => $router.push({name: 'resource-file-create'})" v-ps="['GENERAL_USER']">{{$t('Create File')}}</x-button>
<x-button type="ghost" @click="_uploading" v-ps="['GENERAL_USER']">{{$t('Upload Files')}}</x-button>
</x-button-group>
</template>
</m-conditions>
</template>
<template slot="content">
<template v-if="fileResourcesList.length">
<m-list :file-resources-list="fileResourcesList" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize">
</m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" :page-size="searchParams.pageSize" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!fileResourcesList.length">
<m-no-data></m-no-data>
<m-list-construction :title="$t('File Manage')">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group">
<x-button-group size="small" >
<x-button type="ghost" @click="() => $router.push({name: 'resource-file-create'})" v-ps="['GENERAL_USER']">{{$t('Create File')}}</x-button>
<x-button type="ghost" @click="_uploading" v-ps="['GENERAL_USER']">{{$t('Upload Files')}}</x-button>
</x-button-group>
</template>
<m-spin :is-spin="isLoading">
</m-spin>
</m-conditions>
</template>
<template slot="content">
<template v-if="fileResourcesList.length">
<m-list :file-resources-list="fileResourcesList" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize">
</m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" :page-size="searchParams.pageSize" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!fileResourcesList.length">
<m-no-data></m-no-data>
</template>
</m-list-construction>
</div>
<m-spin :is-spin="isLoading">
</m-spin>
</template>
</m-list-construction>
</template>
<script>
import _ from 'lodash'
@ -38,7 +35,6 @@
import mNoData from '@/module/components/noData/noData'
import listUrlParamHandle from '@/module/mixin/listUrlParamHandle'
import mConditions from '@/module/components/conditions/conditions'
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
import mListConstruction from '@/module/components/listConstruction/listConstruction'
export default {
@ -100,6 +96,6 @@
},
mounted () {
},
components: { mSecondaryMenu, mListConstruction, mConditions, mList, mSpin, mNoData }
components: { mListConstruction, mConditions, mList, mSpin, mNoData }
}
</script>

48
escheduler-ui/src/js/conf/home/pages/resource/pages/udf/pages/function/index.vue

@ -1,30 +1,27 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'resource'"></m-secondary-menu>
<m-list-construction :title="$t('UDF Function')">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group">
<x-button type="ghost" @click="_create" v-ps="['GENERAL_USER']" size="small" >{{$t('Create UDF Function')}}</x-button>
</template>
</m-conditions>
</template>
<template slot="content">
<template v-if="udfFuncList.length">
<m-list :udf-func-list="udfFuncList" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize" @on-update="_updateList">
</m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" :page-size="searchParams.pageSize" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!udfFuncList.length">
<m-no-data></m-no-data>
<m-list-construction :title="$t('UDF Function')">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group">
<x-button type="ghost" @click="_create" v-ps="['GENERAL_USER']" size="small" >{{$t('Create UDF Function')}}</x-button>
</template>
<m-spin :is-spin="isLoading">
</m-spin>
</m-conditions>
</template>
<template slot="content">
<template v-if="udfFuncList.length">
<m-list :udf-func-list="udfFuncList" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize" @on-update="_updateList">
</m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" :page-size="searchParams.pageSize" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!udfFuncList.length">
<m-no-data></m-no-data>
</template>
</m-list-construction>
</div>
<m-spin :is-spin="isLoading">
</m-spin>
</template>
</m-list-construction>
</template>
<script>
import _ from 'lodash'
@ -35,7 +32,6 @@
import mNoData from '@/module/components/noData/noData'
import listUrlParamHandle from '@/module/mixin/listUrlParamHandle'
import mConditions from '@/module/components/conditions/conditions'
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
import mListConstruction from '@/module/components/listConstruction/listConstruction'
export default {
@ -116,6 +112,6 @@
},
mounted () {
},
components: { mSecondaryMenu, mListConstruction, mConditions, mList, mSpin, mCreateUdf, mNoData }
components: { mListConstruction, mConditions, mList, mSpin, mCreateUdf, mNoData }
}
</script>

8
escheduler-ui/src/js/conf/home/pages/resource/pages/udf/pages/resource/index.vue

@ -1,7 +1,5 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'resource'"></m-secondary-menu>
<m-list-construction :title="$t('UDF Resources')">
<m-list-construction :title="$t('UDF Resources')">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group">
@ -24,7 +22,6 @@
</m-spin>
</template>
</m-list-construction>
</div>
</template>
<script>
import _ from 'lodash'
@ -35,7 +32,6 @@
import mNoData from '@/module/components/noData/noData'
import listUrlParamHandle from '@/module/mixin/listUrlParamHandle'
import mConditions from '@/module/components/conditions/conditions'
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
import mListConstruction from '@/module/components/listConstruction/listConstruction'
export default {
@ -98,6 +94,6 @@
},
mounted () {
},
components: { mSecondaryMenu, mListConstruction, mConditions, mList, mSpin, mNoData }
components: { mListConstruction, mConditions, mList, mSpin, mNoData }
}
</script>

9
escheduler-ui/src/js/conf/home/pages/security/index.vue

@ -1,8 +1,13 @@
<template>
<router-view></router-view>
<div class="main-layout-box">
<m-secondary-menu :type="'security'"></m-secondary-menu>
<router-view></router-view>
</div>
</template>
<script>
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
export default {
name: 'security-index'
name: 'security-index',
components: { mSecondaryMenu }
}
</script>

46
escheduler-ui/src/js/conf/home/pages/security/pages/queue/index.vue

@ -1,30 +1,25 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'security'"></m-secondary-menu>
<template>
<m-list-construction :title="$t('Queue manage')">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group">
<x-button type="ghost" size="small" @click="_create('')">{{$t('Create queue')}}</x-button>
</template>
</m-conditions>
<m-list-construction :title="$t('Queue manage')">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group">
<x-button type="ghost" size="small" @click="_create('')">{{$t('Create queue')}}</x-button>
</template>
<template slot="content">
<template v-if="queueList.length">
<m-list :queue-list="queueList" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize"></m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" :page-size="searchParams.pageSize" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!queueList.length">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading"></m-spin>
</template>
</m-list-construction>
</m-conditions>
</template>
<template slot="content">
<template v-if="queueList.length">
<m-list :queue-list="queueList" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize"></m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" :page-size="searchParams.pageSize" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!queueList.length">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading"></m-spin>
</template>
</div>
</m-list-construction>
</template>
<script>
import _ from 'lodash'
@ -35,7 +30,6 @@
import mNoData from '@/module/components/noData/noData'
import listUrlParamHandle from '@/module/mixin/listUrlParamHandle'
import mConditions from '@/module/components/conditions/conditions'
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
import mListConstruction from '@/module/components/listConstruction/listConstruction'
export default {
@ -116,6 +110,6 @@
mounted () {
},
components: { mSecondaryMenu, mList, mListConstruction, mConditions, mSpin, mNoData }
components: { mList, mListConstruction, mConditions, mSpin, mNoData }
}
</script>

30
escheduler-ui/src/js/conf/home/pages/security/pages/servers/pages/master/index.vue

@ -1,26 +1,22 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'security'"></m-secondary-menu>
<m-list-construction :title="$t('Service-Master')">
<template slot="content">
<template v-if="masterList.length">
<m-list :list="masterList"></m-list>
</template>
<template v-if="!masterList.length">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading" ></m-spin>
<m-list-construction :title="$t('Service-Master')">
<template slot="content">
<template v-if="masterList.length">
<m-list :list="masterList"></m-list>
</template>
</m-list-construction>
</div>
<template v-if="!masterList.length">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading" ></m-spin>
</template>
</m-list-construction>
</template>
<script>
import { mapActions } from 'vuex'
import mListConstruction from '@/module/components/listConstruction/listConstruction'
import mSpin from '@/module/components/spin/spin'
import mList from '../../_source/list'
import mSpin from '@/module/components/spin/spin'
import mNoData from '@/module/components/noData/noData'
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
import mListConstruction from '@/module/components/listConstruction/listConstruction'
export default {
name: 'servers-master',
@ -48,6 +44,6 @@
},
mounted () {
},
components: { mList, mListConstruction, mSpin, mNoData, mSecondaryMenu }
components: { mList, mListConstruction, mSpin, mNoData }
}
</script>

26
escheduler-ui/src/js/conf/home/pages/security/pages/servers/pages/worker/index.vue

@ -1,25 +1,21 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'security'"></m-secondary-menu>
<m-list-construction :title="$t('Service-Worker')">
<template slot="content">
<template v-if="workerList.length">
<m-list :list="workerList"></m-list>
</template>
<template v-if="!workerList.length">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading" ></m-spin>
<m-list-construction :title="$t('Service-Worker')">
<template slot="content">
<template v-if="workerList.length">
<m-list :list="workerList"></m-list>
</template>
</m-list-construction>
</div>
<template v-if="!workerList.length">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading" ></m-spin>
</template>
</m-list-construction>
</template>
<script>
import { mapActions } from 'vuex'
import mList from '../../_source/list'
import mSpin from '@/module/components/spin/spin'
import mNoData from '@/module/components/noData/noData'
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
import mListConstruction from '@/module/components/listConstruction/listConstruction'
export default {
@ -48,6 +44,6 @@
},
mounted () {
},
components: { mList, mListConstruction, mSpin, mNoData, mSecondaryMenu }
components: { mList, mListConstruction, mSpin, mNoData }
}
</script>

46
escheduler-ui/src/js/conf/home/pages/security/pages/tenement/index.vue

@ -1,30 +1,25 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'security'"></m-secondary-menu>
<template>
<m-list-construction :title="$t('Tenant Manage')">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group">
<x-button type="ghost" size="small" @click="_create('')">{{$t('Create Tenant')}}</x-button>
</template>
</m-conditions>
<m-list-construction :title="$t('Tenant Manage')">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group">
<x-button type="ghost" size="small" @click="_create('')">{{$t('Create Tenant')}}</x-button>
</template>
<template slot="content">
<template v-if="tenementList.length">
<m-list :tenement-list="tenementList" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize"></m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" :page-size="searchParams.pageSize" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!tenementList.length">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading"></m-spin>
</template>
</m-list-construction>
</m-conditions>
</template>
<template slot="content">
<template v-if="tenementList.length">
<m-list :tenement-list="tenementList" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize"></m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" :page-size="searchParams.pageSize" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!tenementList.length">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading"></m-spin>
</template>
</div>
</m-list-construction>
</template>
<script>
import _ from 'lodash'
@ -35,7 +30,6 @@
import mNoData from '@/module/components/noData/noData'
import listUrlParamHandle from '@/module/mixin/listUrlParamHandle'
import mConditions from '@/module/components/conditions/conditions'
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
import mListConstruction from '@/module/components/listConstruction/listConstruction'
export default {
@ -115,6 +109,6 @@
},
mounted () {
},
components: { mSecondaryMenu, mList, mListConstruction, mConditions, mSpin, mNoData }
components: { mList, mListConstruction, mConditions, mSpin, mNoData }
}
</script>

50
escheduler-ui/src/js/conf/home/pages/security/pages/users/index.vue

@ -1,30 +1,25 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'security'"></m-secondary-menu>
<template>
<m-list-construction :title="$t('User Manage')">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group">
<x-button type="ghost" size="small" @click="_create('')">{{$t('Create User')}}</x-button>
</template>
</m-conditions>
<m-list-construction :title="$t('User Manage')">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group">
<x-button type="ghost" size="small" @click="_create('')">{{$t('Create User')}}</x-button>
</template>
<template slot="content">
<template v-if="userList.length">
<m-list :user-list="userList" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize"></m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" :page-size="searchParams.pageSize" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!userList.length">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading"></m-spin>
</template>
</m-list-construction>
</m-conditions>
</template>
<template slot="content">
<template v-if="userList.length">
<m-list :user-list="userList" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize"></m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" :page-size="searchParams.pageSize" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!userList.length">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading"></m-spin>
</template>
</div>
</m-list-construction>
</template>
<script>
import _ from 'lodash'
@ -35,7 +30,6 @@
import mNoData from '@/module/components/noData/noData'
import listUrlParamHandle from '@/module/mixin/listUrlParamHandle'
import mConditions from '@/module/components/conditions/conditions'
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
import mListConstruction from '@/module/components/listConstruction/listConstruction'
export default {
@ -55,7 +49,7 @@
mixins: [listUrlParamHandle],
props: {},
methods: {
...mapActions('security', ['getUsersList']),
...mapActions('security', ['getUsersListP']),
/**
* Query
*/
@ -94,7 +88,7 @@
},
_getList (flag) {
this.isLoading = !flag
this.getUsersList(this.searchParams).then(res => {
this.getUsersListP(this.searchParams).then(res => {
this.userList = []
this.userList = res.totalList
this.total = res.total
@ -115,6 +109,6 @@
},
mounted () {
},
components: { mSecondaryMenu, mList, mListConstruction, mConditions, mSpin, mNoData }
components: { mList, mListConstruction, mConditions, mSpin, mNoData }
}
</script>

46
escheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/index.vue

@ -1,30 +1,25 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'security'"></m-secondary-menu>
<template>
<m-list-construction :title="'Warning group manage'">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group">
<x-button type="ghost" size="small" @click="_create('')">{{$t('Create alarm group')}}</x-button>
</template>
</m-conditions>
<m-list-construction :title="$t('Warning group manage')">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group">
<x-button type="ghost" size="small" @click="_create('')">{{$t('Create alarm group')}}</x-button>
</template>
<template slot="content">
<template v-if="alertgroupList.length">
<m-list :alertgroup-list="alertgroupList" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize"></m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" :page-size="searchParams.pageSize" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!alertgroupList.length">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading"></m-spin>
</template>
</m-list-construction>
</m-conditions>
</template>
<template slot="content">
<template v-if="alertgroupList.length">
<m-list :alertgroup-list="alertgroupList" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize"></m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" :page-size="searchParams.pageSize" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!alertgroupList.length">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading"></m-spin>
</template>
</div>
</m-list-construction>
</template>
<script>
import _ from 'lodash'
@ -35,7 +30,6 @@
import mNoData from '@/module/components/noData/noData'
import listUrlParamHandle from '@/module/mixin/listUrlParamHandle'
import mConditions from '@/module/components/conditions/conditions'
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
import mListConstruction from '@/module/components/listConstruction/listConstruction'
export default {
@ -115,6 +109,6 @@
},
mounted () {
},
components: { mSecondaryMenu, mList, mListConstruction, mConditions, mSpin, mNoData }
components: { mList, mListConstruction, mConditions, mSpin, mNoData }
}
</script>

10
escheduler-ui/src/js/conf/home/pages/user/index.vue

@ -1,8 +1,14 @@
<template>
<router-view></router-view>
<div class="main-layout-box">
<m-secondary-menu :type="'user'"></m-secondary-menu>
<router-view></router-view>
</div>
</template>
<script>
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
export default {
name: 'user-index'
name: 'user-index',
components: { mSecondaryMenu }
}
</script>

16
escheduler-ui/src/js/conf/home/pages/user/pages/account/index.vue

@ -1,20 +1,16 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'user'"></m-secondary-menu>
<m-list-construction :title="$t('User Information')">
<template slot="content">
<m-info></m-info>
</template>
</m-list-construction>
</div>
<m-list-construction :title="$t('User Information')">
<template slot="content">
<m-info></m-info>
</template>
</m-list-construction>
</template>
<script>
import mInfo from './_source/info'
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
import mListConstruction from '@/module/components/listConstruction/listConstruction'
export default {
name: 'account-index',
components: { mSecondaryMenu, mListConstruction, mInfo }
components: { mListConstruction, mInfo }
}
</script>

16
escheduler-ui/src/js/conf/home/pages/user/pages/password/index.vue

@ -1,20 +1,16 @@
<template>
<div class="main-layout-box">
<m-secondary-menu :type="'user'"></m-secondary-menu>
<m-list-construction :title="$t('Edit Password')">
<template slot="content">
<m-info></m-info>
</template>
</m-list-construction>
</div>
<m-list-construction :title="$t('Edit Password')">
<template slot="content">
<m-info></m-info>
</template>
</m-list-construction>
</template>
<script>
import mInfo from './_source/info'
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
import mListConstruction from '@/module/components/listConstruction/listConstruction'
export default {
name: 'password-index',
components: { mSecondaryMenu, mListConstruction, mInfo }
components: { mListConstruction, mInfo }
}
</script>

152
escheduler-ui/src/js/conf/home/pages/user/pages/token/_source/createToken.vue

@ -0,0 +1,152 @@
<template>
<m-popup
ref="popup"
:ok-text="item ? $t('Edit') : $t('Submit')"
:nameText="item ? '编辑令牌' : '创建令牌'"
@ok="_ok">
<template slot="content">
<div class="create-token-model">
<m-list-box-f>
<template slot="name"><b>*</b>失效时间</template>
<template slot="content">
<x-datepicker
:disabled-date="disabledDate"
v-model="expireTime"
@on-change="_onChange"
format="YYYY-MM-DD HH:mm:ss"
:panelNum="1">
</x-datepicker>
</template>
</m-list-box-f>
<m-list-box-f>
<template slot="name"><b>*</b>用户</template>
<template slot="content">
<x-select v-model="userId" @on-change="_onChange">
<x-option
v-for="city in userIdList"
:key="city.id"
:value="city.id"
:label="city.userName">
</x-option>
</x-select>
</template>
</m-list-box-f>
<m-list-box-f>
<template slot="name">Token</template>
<template slot="content">
<x-input
readonly
style="width: 330px;"
type="input"
v-model="token"
placeholder="请输入Token">
</x-input>
<x-button type="ghost" @click="_generateToken" :loading="tokenLoading">生成Token</x-button>
</template>
</m-list-box-f>
</div>
</template>
</m-popup>
</template>
<script>
import _ from 'lodash'
import dayjs from 'dayjs'
// import i18n from '@/module/i18n'
import store from '@/conf/home/store'
import mPopup from '@/module/components/popup/popup'
import mListBoxF from '@/module/components/listBoxF/listBoxF'
export default {
name: 'create-token',
data () {
return {
store,
expireTime: dayjs().format('YYYY-MM-DD 23:59:59'),
userId: null,
disabledDate: date => (date.getTime() - new Date(new Date().getTime() - 24 * 60 * 60 * 1000)) < 0,
token: '',
userIdList: [],
tokenLoading: false
}
},
props: {
item: Object
},
methods: {
_ok () {
if (this._verification()) {
this._submit()
}
},
_verification () {
if (!this.token) {
this.$message.warning('请生成Token')
return false
}
return true
},
_submit () {
let param = {
expireTime: dayjs(this.expireTime).format('YYYY-MM-DD HH:mm:ss'),
userId: this.userId,
token: this.token
}
if (this.item) {
param.id = this.item.id
}
this.$refs['popup'].spinnerLoading = true
this.store.dispatch(`user/${this.item ? 'updateToken' : 'createToken'}`, param).then(res => {
this.$emit('onUpdate')
this.$message.success(res.msg)
setTimeout(() => {
this.$refs['popup'].spinnerLoading = false
}, 800)
}).catch(e => {
this.$message.error(e.msg || '')
this.$refs['popup'].spinnerLoading = false
})
},
_generateToken () {
this.tokenLoading = true
this.store.dispatch(`user/generateToken`, {
userId: this.userId,
expireTime: this.expireTime
}).then(res => {
setTimeout(() => {
this.tokenLoading = false
this.token = res
}, 1200)
}).catch(e => {
this.token = ''
this.$message.error(e.msg || '')
this.tokenLoading = false
})
},
_onChange () {
this.token = ''
}
},
watch: {},
created () {
this.store.dispatch(`security/getUsersList`).then(res => {
this.userIdList = _.map(res, v => _.pick(v, ['id', 'userName']))
if (this.item) {
this.expireTime = this.item.expireTime
this.userId = this.item.userId
this.token = this.item.token
} else {
this.userId = this.userIdList[0].id
}
})
},
mounted () {
},
components: { mPopup, mListBoxF }
}
</script>
<style lang="scss" rel="stylesheet/scss">
.create-token-model {
width: 640px;
}
</style>

125
escheduler-ui/src/js/conf/home/pages/user/pages/token/_source/list.vue

@ -0,0 +1,125 @@
<template>
<div class="list-model">
<div class="table-box">
<table>
<tr>
<th>
<span>编号</span>
</th>
<th>
<span>用户</span>
</th>
<th>
<span>Token</span>
</th>
<th>
<span>开始时间</span>
</th>
<th>
<span>失效时间</span>
</th>
<th>
<span>创建时间</span>
</th>
<th>
<span>更新时间</span>
</th>
<th width="120">
<span>{{$t('Operation')}}</span>
</th>
</tr>
<tr v-for="(item, $index) in list" :key="$index">
<td>
<span>{{parseInt(pageNo === 1 ? ($index + 1) : (($index + 1) + (pageSize * (pageNo - 1))))}}</span>
</td>
<td>
<span>
<a href="javascript:" class="links">{{item.userName}}</a>
</span>
</td>
<td><span>{{item.token}}</span></td>
<td>
<span>{{item.createTime | formatDate}}</span>
</td>
<td>
<span>{{item.expireTime | formatDate}}</span>
</td>
<td><span>{{item.createTime | formatDate}}</span></td>
<td><span>{{item.updateTime | formatDate}}</span></td>
<td>
<x-button type="info" shape="circle" size="xsmall" data-toggle="tooltip" icon="iconfont icon-bianjixiugai" :title="$t('Edit')" @click="_edit(item)">
</x-button>
<x-poptip
:ref="'poptip-delete-' + $index"
placement="bottom-end"
width="90">
<p>{{$t('Delete?')}}</p>
<div style="text-align: right; margin: 0;padding-top: 4px;">
<x-button type="text" size="xsmall" shape="circle" @click="_closeDelete($index)">{{$t('Cancel')}}</x-button>
<x-button type="primary" size="xsmall" shape="circle" @click="_delete(item,$index)">{{$t('Confirm')}}</x-button>
</div>
<template slot="reference">
<x-button type="error" shape="circle" size="xsmall" data-toggle="tooltip" icon="iconfont icon-shanchu" :title="$t('delete')">
</x-button>
</template>
</x-poptip>
</td>
</tr>
</table>
</div>
</div>
</template>
<script>
import { mapActions } from 'vuex'
import '@/module/filter/formatDate'
import { findComponentDownward } from '@/module/util/'
export default {
name: 'token-list',
data () {
return {
list: []
}
},
props: {
tokenList: Array,
pageNo: Number,
pageSize: Number
},
methods: {
...mapActions('user', ['deleteToken']),
_closeDelete (i) {
this.$refs[`poptip-delete-${i}`][0].doClose()
},
_delete (item, i) {
this.deleteToken({
id: item.id
}).then(res => {
this.$refs[`poptip-delete-${i}`][0].doClose()
this.list.splice(i, 1)
this.$message.success(res.msg)
}).catch(e => {
this.$refs[`poptip-delete-${i}`][0].doClose()
this.$message.error(e.msg || '')
})
},
_edit (item) {
findComponentDownward(this.$root, 'token-index')._create(item)
}
},
watch: {
tokenList (a) {
this.list = []
setTimeout(() => {
this.list = a
})
}
},
created () {
this.list = this.tokenList
},
mounted () {
},
components: { }
}
</script>

115
escheduler-ui/src/js/conf/home/pages/user/pages/token/index.vue

@ -0,0 +1,115 @@
<template>
<m-list-construction :title="'令牌管理'">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group">
<x-button type="ghost" size="small" @click="_create('')">创建令牌</x-button>
</template>
</m-conditions>
</template>
<template slot="content">
<template v-if="tokenList.length">
<m-list :token-list="tokenList" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize"></m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" :page-size="searchParams.pageSize" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!tokenList.length">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading"></m-spin>
</template>
</m-list-construction>
</template>
<script>
import _ from 'lodash'
import { mapActions } from 'vuex'
import mList from './_source/list'
import mSpin from '@/module/components/spin/spin'
import mCreateToken from './_source/createToken'
import mNoData from '@/module/components/noData/noData'
import listUrlParamHandle from '@/module/mixin/listUrlParamHandle'
import mConditions from '@/module/components/conditions/conditions'
import mSecondaryMenu from '@/module/components/secondaryMenu/secondaryMenu'
import mListConstruction from '@/module/components/listConstruction/listConstruction'
export default {
name: 'token-index',
data () {
return {
total: null,
isLoading: false,
tokenList: [],
searchParams: {
pageSize: 10,
pageNo: 1,
searchVal: ''
}
}
},
mixins: [listUrlParamHandle],
props: {},
methods: {
...mapActions('user', ['getTokenListP']),
/**
* Inquire
*/
_onConditions (o) {
this.searchParams = _.assign(this.searchParams, o)
this.searchParams.pageNo = 1
},
_page (val) {
this.searchParams.pageNo = val
},
_create (item) {
let self = this
let modal = this.$modal.dialog({
closable: false,
showMask: true,
escClose: true,
className: 'v-modal-custom',
transitionName: 'opacityp',
render (h) {
return h(mCreateToken, {
on: {
onUpdate () {
self._debounceGET('false')
modal.remove()
},
close () {
modal.remove()
}
},
props: {
item: item
}
})
}
})
},
_getList (flag) {
this.isLoading = !flag
this.getTokenListP(this.searchParams).then(res => {
this.tokenList = []
this.tokenList = res.totalList
this.total = res.total
this.isLoading = false
}).catch(e => {
this.isLoading = false
})
}
},
watch: {
// router
'$route' (a) {
// url no params get instance list
this.searchParams.pageNo = _.isEmpty(a.query) ? 1 : a.query.pageNo
}
},
created () {
},
mounted () {
},
components: { mSecondaryMenu, mList, mListConstruction, mConditions, mSpin, mNoData }
}
</script>

8
escheduler-ui/src/js/conf/home/router/index.js

@ -375,6 +375,14 @@ const router = new Router({
meta: {
title: `${i18n.$t('Edit password')}`
}
},
{
path: '/user/token',
name: 'token',
component: resolve => require(['../pages/user/pages/token/index'], resolve),
meta: {
title: `令牌管理`
}
}
]
}

14
escheduler-ui/src/js/conf/home/store/security/actions.js

@ -90,7 +90,7 @@ export default {
* @param "searchVal":string,
* @param "pageSize":int
*/
getUsersList ({ state }, payload) {
getUsersListP ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get(`users/list-paging`, payload, res => {
resolve(res.data)
@ -99,6 +99,18 @@ export default {
})
})
},
/**
* Paging query user list
*/
getUsersList ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get(`users/list`, payload, res => {
resolve(res.data)
}).catch(e => {
reject(e)
})
})
},
/**
* Update user
* @param "id":int,

77
escheduler-ui/src/js/conf/home/store/user/actions.js

@ -42,5 +42,82 @@ export default {
}).catch(e => {
console.log(e)
})
},
/**
* get token list
* User loginUser,
* Integer pageNo,
* String searchVal,
* Integer pageSize
*/
getTokenListP ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get(`access-token/list-paging`, payload, res => {
resolve(res.data)
}).catch(e => {
reject(e)
})
})
},
/**
* create token
* User loginUser,
* int userId,
* String expireTime,
* String token
*/
createToken ({ state }, payload) {
return new Promise((resolve, reject) => {
io.post(`access-token/create`, payload, res => {
resolve(res)
}).catch(e => {
reject(e)
})
})
},
/**
* update token
* User loginUser,
* int userId,
* String expireTime,
* String token
*/
updateToken ({ state }, payload) {
return new Promise((resolve, reject) => {
io.post(`access-token/update`, payload, res => {
resolve(res)
}).catch(e => {
reject(e)
})
})
},
/**
* create token
* User loginUser,
* int userId,
* String expireTime
*/
generateToken ({ state }, payload) {
return new Promise((resolve, reject) => {
io.post(`access-token/generate`, payload, res => {
resolve(res.data)
}).catch(e => {
reject(e)
})
})
},
/**
* delete token
* User loginUser,
* int id
*/
deleteToken ({ state }, payload) {
return new Promise((resolve, reject) => {
io.post(`access-token/delete`, payload, res => {
resolve(res)
}).catch(e => {
reject(e)
})
})
}
}

6
escheduler-ui/src/js/module/components/conditions/conditions.vue

@ -53,6 +53,12 @@
return this.$slots['search-group']
}
},
created () {
// Routing parameter merging
if (!_.isEmpty(this.$route.query)) {
this.searchVal = this.$route.query.searchVal || ''
}
},
components: {}
}
</script>

4
escheduler-ui/src/js/module/components/nav/nav.vue

@ -32,13 +32,13 @@
</router-link>
</div>
</div>
<!--<div class="clearfix list">
<div class="clearfix list">
<div class="nav-links">
<router-link :to="{ path: '/monitor'}" tag="a" active-class="active">
<span><i class="iconfont">&#xe65f;</i>监控中心</span><b></b>
</router-link>
</div>
</div>-->
</div>
<div class="clearfix list" >
<div class="nav-links">
<router-link :to="{ path: '/security'}" tag="a" active-class="active" v-ps="['ADMIN_USER']">

0
escheduler-ui/src/js/module/components/secondaryMenu/close.png → escheduler-ui/src/js/module/components/secondaryMenu/_source/close.png

Before

Width:  |  Height:  |  Size: 550 B

After

Width:  |  Height:  |  Size: 550 B

56
escheduler-ui/src/js/module/components/secondaryMenu/menu.js → escheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js

@ -16,6 +16,9 @@
*/
import i18n from '@/module/i18n'
import config from '~/external/config'
import Permissions from '@/module/permissions'
let menu = {
projects: [
{
@ -23,6 +26,7 @@ let menu = {
id: 1,
path: 'projects-index',
isOpen: true,
disabled: true,
icon: 'fa-home',
children: []
},
@ -31,32 +35,38 @@ let menu = {
id: 2,
path: '',
isOpen: true,
disabled: true,
icon: 'fa-gear',
children: [
{
name: `${i18n.$t('Process definition')}`,
path: 'definition',
id: 1
id: 1,
disabled: true
},
{
name: `${i18n.$t('Process Instance')}`,
path: 'instance',
id: 2
id: 2,
disabled: true
},
{
name: `${i18n.$t('Task Instance')}`,
path: 'task-instance',
id: 3
id: 3,
disabled: true
},
{
name: `${i18n.$t('Task record')}`,
path: 'task-record',
id: 4
id: 4,
disabled: config.recordSwitch
},
{
name: `${i18n.$t('History task record')}`,
path: 'history-task-record',
id: 5
id: 5,
disabled: config.recordSwitch
}
]
}
@ -68,6 +78,7 @@ let menu = {
id: 1,
path: 'tenement-manage',
isOpen: true,
disabled: true,
icon: 'fa-users',
children: []
},
@ -76,6 +87,7 @@ let menu = {
id: 1,
path: 'users-manage',
isOpen: true,
disabled: true,
icon: 'fa-user-circle',
children: []
},
@ -84,6 +96,7 @@ let menu = {
id: 1,
path: 'warning-groups-manage',
isOpen: true,
disabled: true,
icon: 'fa-warning',
children: []
},
@ -92,6 +105,7 @@ let menu = {
id: 1,
path: 'queue-manage',
isOpen: true,
disabled: true,
icon: 'fa-recycle',
children: []
},
@ -100,17 +114,20 @@ let menu = {
id: 1,
path: '',
isOpen: true,
disabled: true,
icon: 'fa-server',
children: [
{
name: 'master',
path: 'servers-master',
id: 1
id: 1,
disabled: true
},
{
name: 'worker',
path: 'servers-worker',
id: 2
id: 2,
disabled: true
}
]
}
@ -123,7 +140,7 @@ let menu = {
isOpen: true,
icon: 'fa-files-o',
children: [],
disabled: false
disabled: true
},
{
name: `${i18n.$t('UDF manage')}`,
@ -131,17 +148,19 @@ let menu = {
path: '',
isOpen: true,
icon: 'fa-file-text',
disabled: false,
disabled: true,
children: [
{
name: `${i18n.$t('Resource manage')}`,
path: 'resource-udf-resource',
id: 1
id: 1,
disabled: true
},
{
name: `${i18n.$t('Function manage')}`,
path: 'resource-udf-function',
id: 2
id: 2,
disabled: true
}
]
}
@ -149,12 +168,12 @@ let menu = {
user: [
{
name: `${i18n.$t('User Information')}`,
id: 1,
id: 0,
path: 'account',
isOpen: true,
icon: 'fa-user',
children: [],
disabled: false
disabled: true
},
{
name: `${i18n.$t('Edit password')}`,
@ -163,7 +182,16 @@ let menu = {
isOpen: true,
icon: 'fa-key',
children: [],
disabled: false
disabled: true
},
{
name: `令牌管理`,
id: 2,
path: 'token',
isOpen: true,
icon: 'fa-file-text',
children: [],
disabled: !Permissions.getAuth()
}
]
}

0
escheduler-ui/src/js/module/components/secondaryMenu/open.png → escheduler-ui/src/js/module/components/secondaryMenu/_source/open.png

Before

Width:  |  Height:  |  Size: 586 B

After

Width:  |  Height:  |  Size: 586 B

49
escheduler-ui/src/js/module/components/secondaryMenu/secondaryMenu.vue

@ -3,11 +3,21 @@
<div class="toogle-box">
<a href="javascript:" class="tog-close" @click="_toggleMenu" v-if="!isTogHide"></a>
<a href="javascript:" class="tog-open" @click="_toggleMenu" v-if="isTogHide"></a>
<!--<a href="javascriipt:" @click="_toggleMenu"><i class="iconfont">{{isTogHide ?'&#xeef5;' : '&#xe652;'}}</i></a>-->
</div>
<div class="leven-1" v-for="(item,$index) in menuList">
<template v-if="item.path">
<router-link :to="{ name: item.path}">
<div v-if="item.disabled">
<template v-if="item.path">
<router-link :to="{ name: item.path}">
<div class="name" @click="_toggleSubMenu(item)">
<a href="javascript:">
<i class="fa icon" :class="item.icon"></i>
<span>{{item.name}}</span>
<i class="fa angle" :class="item.isOpen ? 'fa-angle-down' : 'fa-angle-right'" v-if="item.children.length"></i>
</a>
</div>
</router-link>
</template>
<template v-if="!item.path">
<div class="name" @click="_toggleSubMenu(item)">
<a href="javascript:">
<i class="fa icon" :class="item.icon"></i>
@ -15,27 +25,20 @@
<i class="fa angle" :class="item.isOpen ? 'fa-angle-down' : 'fa-angle-right'" v-if="item.children.length"></i>
</a>
</div>
</router-link>
</template>
<template v-if="!item.path">
<div class="name" @click="_toggleSubMenu(item)">
<a href="javascript:">
<i class="fa icon" :class="item.icon"></i>
<span>{{item.name}}</span>
<i class="fa angle" :class="item.isOpen ? 'fa-angle-down' : 'fa-angle-right'" v-if="item.children.length"></i>
</a>
</div>
</template>
<ul v-if="item.isOpen && item.children.length">
<router-link :to="{ name: el.path}" tag="li" active-class="active" v-for="(el,index) in item.children">
<span>{{el.name}}</span>
</router-link>
</ul>
</template>
<ul v-if="item.isOpen && item.children.length">
<template v-for="(el,index) in item.children">
<router-link :to="{ name: el.path}" tag="li" active-class="active" v-if="el.disabled">
<span>{{el.name}}</span>
</router-link>
</template>
</ul>
</div>
</div>
</div>
</template>
<script>
import menu from './menu'
import menu from './_source/menu'
export default {
name: 'secondary-menu',
@ -94,13 +97,13 @@
.tog-close {
width: 12px;
height: 102px;
background: url("./close.png") no-repeat;
background: url("./_source/close.png") no-repeat;
display: inline-block;
}
.tog-open {
width: 12px;
height: 102px;
background: url("./open.png") no-repeat;
background: url("./_source/open.png") no-repeat;
display: inline-block;
position: absolute;
right: -12px;
@ -114,7 +117,7 @@
line-height: 40px;
display: block;
position: relative;
padding-left: 12px;
padding-left: 10px;
>.icon {
vertical-align: middle;
font-size: 15px;

2
escheduler-ui/src/js/module/i18n/locale/zh_CN.js

@ -410,5 +410,5 @@ export default {
'History task record': '历史任务记录',
'Please go online': '不要忘记上线',
'Queue value': '队列值',
'Please enter queue value': '请输入队列值',
'Please enter queue value': '请输入队列值'
}

7
escheduler-ui/src/lib/external/config.js vendored

@ -0,0 +1,7 @@
/**
* project external config
*/
export default {
// qianfan task record switch
recordSwitch:true
}

0
escheduler-ui/src/lib/localData/email.js → escheduler-ui/src/lib/external/email.js vendored

3
escheduler-ui/src/sass/common/index.scss

@ -129,6 +129,9 @@ body{
.main-layout-box {
padding-left: 200px;
&.no {
padding-left: 0;
}
}
.tooltip-cont-model {

2
pom.xml

@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>cn.analysys</groupId>
<artifactId>escheduler</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>1.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>escheduler</name>
<url>http://maven.apache.org</url>

12
script/env/escheduler_env.py vendored

@ -1,12 +0,0 @@
import os
HADOOP_HOME="/opt/soft/hadoop"
SPARK_HOME1="/opt/soft/spark1"
SPARK_HOME2="/opt/soft/spark2"
PYTHON_HOME="/opt/soft/python"
JAVA_HOME="/opt/soft/java"
HIVE_HOME="/opt/soft/hive"
PATH=os.environ['PATH']
PATH="%s/bin:%s/bin:%s/bin:%s/bin:%s/bin:%s/bin:%s"%(HIVE_HOME,HADOOP_HOME,SPARK_HOME1,SPARK_HOME2,JAVA_HOME,PYTHON_HOME,PATH)
os.putenv('PATH','%s'%PATH)
Loading…
Cancel
Save