Browse Source

Merge remote-tracking branch 'upstream/branch-1.0.2' into branch-1.0.2

pull/2/head
gongzijian 5 years ago
parent
commit
d45bf677a4
  1. 10
      escheduler-api/src/main/java/cn/escheduler/api/quartz/QuartzExecutors.java
  2. 7
      escheduler-api/src/main/java/cn/escheduler/api/service/SchedulerService.java
  3. 2
      escheduler-ui/.env
  4. 17
      escheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/sql.vue
  5. 98
      escheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/list.vue
  6. 49
      escheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/list/_source/list.vue
  7. 12
      escheduler-ui/src/js/conf/home/pages/projects/pages/taskInstance/_source/list.vue
  8. 19
      escheduler-ui/src/js/conf/home/pages/security/pages/tenement/_source/list.vue
  9. 36
      escheduler-ui/src/js/conf/home/store/dag/actions.js
  10. 2
      escheduler-ui/src/js/module/i18n/locale/en_US.js
  11. 2
      escheduler-ui/src/js/module/i18n/locale/zh_CN.js

10
escheduler-api/src/main/java/cn/escheduler/api/quartz/QuartzExecutors.java

@ -26,8 +26,8 @@ import org.quartz.impl.matchers.GroupMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Calendar;
import java.util.*;
import java.util.Calendar;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@ -226,8 +226,12 @@ public class QuartzExecutors {
public boolean deleteJob(String jobName, String jobGroupName) {
lock.writeLock().lock();
try {
logger.info("try to delete job, job name: {}, job group name: {},", jobName, jobGroupName);
return scheduler.deleteJob(new JobKey(jobName, jobGroupName));
JobKey jobKey = new JobKey(jobName,jobGroupName);
if(scheduler.checkExists(jobKey)){
logger.info("try to delete job, job name: {}, job group name: {},", jobName, jobGroupName);
return scheduler.deleteJob(jobKey);
}
} catch (SchedulerException e) {
logger.error(String.format("delete job : %s failed",jobName), e);
} finally {

7
escheduler-api/src/main/java/cn/escheduler/api/service/SchedulerService.java

@ -514,6 +514,13 @@ public class SchedulerService extends BaseService {
putMsg(result, Status.SCHEDULE_CRON_NOT_EXISTS, scheduleId);
return result;
}
// Determine if the login user is the owner of the schedule
if (loginUser.getId() != schedule.getUserId()) {
putMsg(result, Status.USER_NO_OPERATION_PERM);
return result;
}
// check schedule is already online
if(schedule.getReleaseState() == ReleaseState.ONLINE){
putMsg(result, Status.SCHEDULE_CRON_STATE_ONLINE,schedule.getId());

2
escheduler-ui/.env

@ -1,5 +1,5 @@
# 后端接口地址11
# 后端接口地址
API_BASE = http://192.168.xx.xx:12345
# 本地开发如需ip访问项目把"#"号去掉

17
escheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/sql.vue

@ -28,6 +28,17 @@
</div>
</m-list-box>
<template v-if="!sqlType && showType.length">
<m-list-box>
<div slot="text">{{$t('Title')}}</div>
<div slot="content">
<x-input
type="input"
v-model="title"
:placeholder="$t('Please enter the title of email')"
autocomplete="off">
</x-input>
</div>
</m-list-box>
<m-list-box>
<div slot="text">{{$t('Recipient')}}</div>
<div slot="content">
@ -141,6 +152,8 @@
udfs: '',
// Sql type
sqlType: 0,
// Email title
title: '',
// Form/attachment
showType: ['TABLE'],
// Sql parameter
@ -241,6 +254,7 @@
sql: editor.getValue(),
udfs: this.udfs,
sqlType: this.sqlType,
title: this.title,
receivers: this.receivers.join(','),
receiversCc: this.receiversCc.join(','),
showType: (() => {
@ -308,6 +322,7 @@
this.showType = []
}
if (val !== 0) {
this.title = ''
this.receivers = []
this.receiversCc = []
}
@ -321,6 +336,7 @@
//
showType (val) {
if (!val.length) {
this.title = ''
this.receivers = []
this.receiversCc = []
}
@ -342,6 +358,7 @@
this.showType = o.params.showType.split(',') || []
this.preStatements = o.params.preStatements || []
this.postStatements = o.params.postStatements || []
this.title = o.params.title || ''
this.receivers = o.params.receivers && o.params.receivers.split(',') || []
this.receiversCc = o.params.receiversCc && o.params.receiversCc.split(',') || []
}

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

@ -1,8 +1,11 @@
<template>
<div class="list-model">
<div class="list-model" style="position: relative;">
<div class="table-box">
<table class="fixed">
<tr>
<th width="50">
<x-checkbox @on-change="_topCheckBoxClick" v-model="checkAll"></x-checkbox>
</th>
<th>
<span>{{$t('#')}}</span>
</th>
@ -29,6 +32,7 @@
</th>
</tr>
<tr v-for="(item, $index) in list" :key="item.id">
<td width="50"><x-checkbox v-model="item.isCheck" @on-change="_arrDelChange"></x-checkbox></td>
<td>
<span>{{parseInt(pageNo === 1 ? ($index + 1) : (($index + 1) + (pageSize * (pageNo - 1))))}}</span>
</td>
@ -60,11 +64,33 @@
<x-button type="error" shape="circle" size="xsmall" data-toggle="tooltip" :title="$t('offline')" @click="_downline(item)" v-if="item.releaseState === 'ONLINE'" v-ps="['GENERAL_USER']" icon="iconfont icon-erji-xiaxianjilu"><!--{{$t('下线')}}--></x-button>
<x-button type="warning" shape="circle" size="xsmall" data-toggle="tooltip" :title="$t('online')" @click="_poponline(item)" v-if="item.releaseState === 'OFFLINE'" v-ps="['GENERAL_USER']" icon="iconfont icon-erji-xiaxianjilu-copy"><!--{{$t('上线')}}--></x-button>
<x-button type="info" shape="circle" size="xsmall" data-toggle="tooltip" :title="$t('Cron Manage')" @click="_timingManage(item)" :disabled="item.releaseState !== 'ONLINE'" v-ps="['GENERAL_USER']" icon="iconfont icon-paibanguanli"><!--{{$t('定时管理')}}--></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
icon="iconfont icon-shanchu"
type="error"
shape="circle"
size="xsmall"
data-toggle="tooltip"
:title="$t('delete')"
v-ps="['GENERAL_USER']">
</x-button>
</template>
</x-poptip>
<x-button type="info" shape="circle" size="xsmall" data-toggle="tooltip" :title="$t('TreeView')" @click="_treeView(item)" icon="iconfont icon-juxingkaobei"><!--{{$t('树形图')}}--></x-button>
</td>
</tr>
</table>
</div>
<x-button style="position: absolute; bottom: -52px; left: 22px;" v-if="strDelete !== ''" @click="_batchDelete">批量删除</x-button>
</div>
</template>
<script>
@ -78,7 +104,9 @@
name: 'definition-list',
data () {
return {
list: []
list: [],
strDelete: '',
checkAll: false
}
},
props: {
@ -87,7 +115,7 @@
pageSize: Number
},
methods: {
...mapActions('dag', ['editProcessState', 'getStartCheck', 'getReceiver']),
...mapActions('dag', ['editProcessState', 'getStartCheck', 'getReceiver', 'deleteDefinition', 'batchDeleteDefinition']),
_rtPublishStatus (code) {
return _.filter(publishStatus, v => v.code === code)[0].desc
},
@ -179,6 +207,27 @@
_timingManage (item) {
this.$router.push({ path: `/projects/definition/list/timing/${item.id}` })
},
/**
* Close the delete layer
*/
_closeDelete (i) {
this.$refs[`poptip-delete-${i}`][0].doClose()
},
/**
* delete
*/
_delete (item, i) {
this.deleteDefinition({
processDefinitionId: item.id
}).then(res => {
this.$refs[`poptip-delete-${i}`][0].doClose()
this._onUpdate()
this.$message.success(res.msg)
}).catch(e => {
this.$refs[`poptip-delete-${i}`][0].doClose()
this.$message.error(e.msg || '')
})
},
/**
* edit
*/
@ -217,6 +266,45 @@
},
_onUpdate () {
this.$emit('on-update')
},
/**
* click the select-all checkbox
*/
_topCheckBoxClick (v) {
this.list.forEach((item, i) => {
this.$set(this.list[i], 'isCheck', v)
})
this._arrDelChange()
},
/**
* the array that to be delete
*/
_arrDelChange (v) {
let arr = []
this.list.forEach((item)=>{
if (item.isCheck) {
arr.push(item.id)
}
})
this.strDelete = _.join(arr, ',')
if (v === false) {
this.checkAll = false
}
},
/**
* batch delete
*/
_batchDelete () {
this.batchDeleteDefinition({
processDefinitionIds: this.strDelete
}).then(res => {
this._onUpdate()
this.checkAll = false
this.$message.success(res.msg)
}).catch(e => {
this.checkAll = false
this.$message.error(e.msg || '')
})
}
},
watch: {
@ -225,6 +313,10 @@
setTimeout(() => {
this.list = a
})
},
pageNo () {
this.checkAll = false
this.strDelete = ''
}
},
created () {

49
escheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/list/_source/list.vue

@ -1,8 +1,11 @@
<template>
<div class="list-model">
<div class="list-model" style="position: relative;">
<div class="table-box">
<table class="fixed">
<tr>
<th width="50">
<x-checkbox @on-change="_topCheckBoxClick" v-model="checkAll"></x-checkbox>
</th>
<th>
<span>{{$t('#')}}</span>
</th>
@ -38,6 +41,7 @@
</th>
</tr>
<tr v-for="(item, $index) in list" :key="item.id">
<td width="50"><x-checkbox v-model="item.isCheck" @on-change="_arrDelChange"></x-checkbox></td>
<td>
<span>{{parseInt(pageNo === 1 ? ($index + 1) : (($index + 1) + (pageSize * (pageNo - 1))))}}</span>
</td>
@ -245,6 +249,7 @@
</tr>
</table>
</div>
<x-button style="position: absolute; bottom: -52px; left: 22px;" v-if="strDelete !== ''" @click="_batchDelete">批量删除</x-button>
</div>
</template>
<script>
@ -259,7 +264,9 @@
//
list: [],
//
buttonType: ''
buttonType: '',
strDelete: '',
checkAll: false
}
},
props: {
@ -268,7 +275,7 @@
pageSize: Number
},
methods: {
...mapActions('dag', ['editExecutorsState', 'deleteInstance']),
...mapActions('dag', ['editExecutorsState', 'deleteInstance', 'batchDeleteInstance']),
/**
* Return run type
*/
@ -440,6 +447,36 @@
},
_gantt (item) {
this.$router.push({ path: `/projects/instance/gantt/${item.id}` })
},
_topCheckBoxClick (v) {
this.list.forEach((item, i) => {
this.$set(this.list[i], 'isCheck', v)
})
this._arrDelChange()
},
_arrDelChange (v) {
let arr = []
this.list.forEach((item)=>{
if (item.isCheck) {
arr.push(item.id)
}
})
this.strDelete = _.join(arr, ',')
if (v === false) {
this.checkAll = false
}
},
_batchDelete () {
this.batchDeleteInstance({
processInstanceIds: this.strDelete
}).then(res => {
this._onUpdate()
this.checkAll = false
this.$message.success(res.msg)
}).catch(e => {
this.checkAll = false
this.$message.error(e.msg || '')
})
}
},
watch: {
@ -448,6 +485,10 @@
setTimeout(() => {
this.list = this._listDataHandle(a)
})
},
pageNo () {
this.checkAll = false
this.strDelete = ''
}
},
created () {
@ -457,4 +498,4 @@
},
components: { }
}
</script>
</script>

12
escheduler-ui/src/js/conf/home/pages/projects/pages/taskInstance/_source/list.vue

@ -45,10 +45,9 @@
<span>{{parseInt(pageNo === 1 ? ($index + 1) : (($index + 1) + (pageSize * (pageNo - 1))))}}</span>
</td>
<td>
<span v-if="isAuth" class="ellipsis"><a href="javascript:" class="links">{{item.name}}</a></span>
<span v-if="!isAuth" class="ellipsis"><a href="javascript:" class="links">{{item.name}}</a></span>
<span class="ellipsis"><a href="javascript:" class="links">{{item.name}}</a></span>
</td>
<td><span class="ellipsis">{{item.processInstanceName}}</span></td>
<td><a href="javascript:" class="links" @click="_go(item)"><span class="ellipsis">{{item.processInstanceName}}</span></a></td>
<td><span>{{item.taskType}}</span></td>
<td><span v-html="_rtState(item.state)" style="cursor: pointer;"></span></td>
<td><span>{{item.submitTime | formatDate}}</span></td>
@ -125,7 +124,10 @@
})
}
})
}
},
_go (item) {
this.$router.push({ path: `/projects/instance/list/${item.processInstanceId}` })
},
},
watch: {
taskInstanceList (a) {
@ -142,4 +144,4 @@
},
components: { }
}
</script>
</script>

19
escheduler-ui/src/js/conf/home/pages/security/pages/tenement/_source/list.vue

@ -64,19 +64,26 @@
@click="_edit(item)"
icon="iconfont icon-bianjixiugai">
</x-button>
<!--<x-poptip
:ref="'poptip-' + $index"
placement="bottom-end"
width="90">
<x-poptip
:ref="'poptip-' + $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" :title="$t('delete')">{{$t('delete')}}</x-button>
<x-button
icon="iconfont icon-shanchu"
type="error"
shape="circle"
size="xsmall"
data-toggle="tooltip"
:title="$t('delete')">
</x-button>
</template>
</x-poptip>-->
</x-poptip>
</td>
</tr>
</table>

36
escheduler-ui/src/js/conf/home/store/dag/actions.js

@ -437,6 +437,42 @@ export default {
})
})
},
/**
* Batch delete process instance
*/
batchDeleteInstance ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get(`projects/${state.projectName}/instance/batch-delete`, payload, res => {
resolve(res)
}).catch(e => {
reject(e)
})
})
},
/**
* Delete definition
*/
deleteDefinition ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get(`projects/${state.projectName}/process/delete`, payload, res => {
resolve(res)
}).catch(e => {
reject(e)
})
})
},
/**
* Batch delete definition
*/
batchDeleteDefinition ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get(`projects/${state.projectName}/process/batch-delete`, payload, res => {
resolve(res)
}).catch(e => {
reject(e)
})
})
},
/**
* Process instance get variable
*/

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

@ -111,6 +111,8 @@ export default {
'Please enter ExecutorPlease enter Executor core number': 'Please enter ExecutorPlease enter Executor core number',
'Core number should be positive integer': 'Core number should be positive integer',
'SQL Type': 'SQL Type',
'Title': 'Title',
'Please enter the title of email': 'Please enter the title of email',
'Table': 'Table',
'Attachment': 'Attachment',
'SQL Parameter': 'SQL Parameter',

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

@ -111,6 +111,8 @@ export default {
'Please enter ExecutorPlease enter Executor core number': '请填写Executor内核数',
'Core number should be positive integer': '内核数为正整数',
'SQL Type': 'sql类型',
'Title': '主题',
'Please enter the title of email': '请输入邮件主题',
'Table': '表格',
'Attachment': '附件',
'SQL Parameter': 'sql参数',

Loading…
Cancel
Save