xxl-job

jobinfo.index.1.js 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. $(function() {
  2. // init date tables
  3. var jobTable = $("#job_list").dataTable({
  4. "deferRender": true,
  5. "processing" : true,
  6. "serverSide": true,
  7. "ajax": {
  8. url: base_url + "/jobinfo/pageList",
  9. type:"post",
  10. data : function ( d ) {
  11. var obj = {};
  12. obj.jobGroup = $('#jobGroup').val();
  13. obj.triggerStatus = $('#triggerStatus').val();
  14. obj.jobDesc = $('#jobDesc').val();
  15. obj.executorHandler = $('#executorHandler').val();
  16. obj.start = d.start;
  17. obj.length = d.length;
  18. return obj;
  19. }
  20. },
  21. "searching": false,
  22. "ordering": false,
  23. //"scrollX": true, // scroll x,close self-adaption
  24. "columns": [
  25. {
  26. "data": 'id',
  27. "bSortable": false,
  28. "visible" : true,
  29. "width":'10%'
  30. },
  31. {
  32. "data": 'jobGroup',
  33. "visible" : false,
  34. "width":'20%',
  35. "render": function ( data, type, row ) {
  36. var groupMenu = $("#jobGroup").find("option");
  37. for ( var index in $("#jobGroup").find("option")) {
  38. if ($(groupMenu[index]).attr('value') == data) {
  39. return $(groupMenu[index]).html();
  40. }
  41. }
  42. return data;
  43. }
  44. },
  45. {
  46. "data": 'jobDesc',
  47. "visible" : true,
  48. "width":'20%'
  49. },
  50. {
  51. "data": 'glueType',
  52. "width":'20%',
  53. "visible" : true,
  54. "render": function ( data, type, row ) {
  55. var glueTypeTitle = findGlueTypeTitle(row.glueType);
  56. if (row.executorHandler) {
  57. return glueTypeTitle +":" + row.executorHandler;
  58. } else {
  59. return glueTypeTitle;
  60. }
  61. }
  62. },
  63. { "data": 'executorParam', "visible" : false},
  64. {
  65. "data": 'jobCron',
  66. "visible" : true,
  67. "width":'10%'
  68. },
  69. {
  70. "data": 'addTime',
  71. "visible" : false,
  72. "render": function ( data, type, row ) {
  73. return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):"";
  74. }
  75. },
  76. {
  77. "data": 'updateTime',
  78. "visible" : false,
  79. "render": function ( data, type, row ) {
  80. return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):"";
  81. }
  82. },
  83. { "data": 'author', "visible" : true, "width":'10%'},
  84. { "data": 'alarmEmail', "visible" : false},
  85. {
  86. "data": 'triggerStatus',
  87. "width":'10%',
  88. "visible" : true,
  89. "render": function ( data, type, row ) {
  90. // status
  91. if (1 == data) {
  92. return '<small class="label label-success" ><i class="fa fa-clock-o"></i>RUNNING</small>';
  93. } else {
  94. return '<small class="label label-default" ><i class="fa fa-clock-o"></i>STOP</small>';
  95. }
  96. return data;
  97. }
  98. },
  99. {
  100. "data": I18n.system_opt ,
  101. "width":'15%',
  102. "render": function ( data, type, row ) {
  103. return function(){
  104. // status
  105. var start_stop = "";
  106. if (1 == row.triggerStatus ) {
  107. start_stop = '<button class="btn btn-primary btn-xs job_operate" _type="job_pause" type="button">'+ I18n.jobinfo_opt_stop +'</button> ';
  108. } else {
  109. start_stop = '<button class="btn btn-primary btn-xs job_operate" _type="job_resume" type="button">'+ I18n.jobinfo_opt_start +'</button> ';
  110. }
  111. // log url
  112. var logUrl = base_url +'/joblog?jobId='+ row.id;
  113. // log url
  114. var codeBtn = "";
  115. if ('BEAN' != row.glueType) {
  116. var codeUrl = base_url +'/jobcode?jobId='+ row.id;
  117. codeBtn = '<a href="'+ codeUrl +'" target="_blank" > <button class="btn btn-warning btn-xs" type="button" >GLUE</button> </a> '
  118. }
  119. // html
  120. tableData['key'+row.id] = row;
  121. var html = '<p id="'+ row.id +'" >'+
  122. '<button class="btn btn-primary btn-xs job_trigger" type="button">'+ I18n.jobinfo_opt_run +'</button> '+
  123. start_stop +
  124. '<a href="'+ logUrl +'"> <button class="btn btn-primary btn-xs" type="job_del" type="button" >'+ I18n.jobinfo_opt_log +'</button> </a> <br> '+
  125. '<button class="btn btn-warning btn-xs update" type="button">'+ I18n.system_opt_edit +'</button> '+
  126. codeBtn +
  127. '<button class="btn btn-danger btn-xs job_operate" _type="job_del" type="button">'+ I18n.system_opt_del +'</button> '+
  128. '</p>';
  129. return html;
  130. };
  131. }
  132. }
  133. ],
  134. "language" : {
  135. "sProcessing" : I18n.dataTable_sProcessing ,
  136. "sLengthMenu" : I18n.dataTable_sLengthMenu ,
  137. "sZeroRecords" : I18n.dataTable_sZeroRecords ,
  138. "sInfo" : I18n.dataTable_sInfo ,
  139. "sInfoEmpty" : I18n.dataTable_sInfoEmpty ,
  140. "sInfoFiltered" : I18n.dataTable_sInfoFiltered ,
  141. "sInfoPostFix" : "",
  142. "sSearch" : I18n.dataTable_sSearch ,
  143. "sUrl" : "",
  144. "sEmptyTable" : I18n.dataTable_sEmptyTable ,
  145. "sLoadingRecords" : I18n.dataTable_sLoadingRecords ,
  146. "sInfoThousands" : ",",
  147. "oPaginate" : {
  148. "sFirst" : I18n.dataTable_sFirst ,
  149. "sPrevious" : I18n.dataTable_sPrevious ,
  150. "sNext" : I18n.dataTable_sNext ,
  151. "sLast" : I18n.dataTable_sLast
  152. },
  153. "oAria" : {
  154. "sSortAscending" : I18n.dataTable_sSortAscending ,
  155. "sSortDescending" : I18n.dataTable_sSortDescending
  156. }
  157. }
  158. });
  159. // table data
  160. var tableData = {};
  161. // search btn
  162. $('#searchBtn').on('click', function(){
  163. jobTable.fnDraw();
  164. });
  165. // jobGroup change
  166. $('#jobGroup').on('change', function(){
  167. //reload
  168. var jobGroup = $('#jobGroup').val();
  169. window.location.href = base_url + "/jobinfo?jobGroup=" + jobGroup;
  170. });
  171. // job operate
  172. $("#job_list").on('click', '.job_operate',function() {
  173. var typeName;
  174. var url;
  175. var needFresh = false;
  176. var type = $(this).attr("_type");
  177. if ("job_pause" == type) {
  178. typeName = I18n.jobinfo_opt_stop ;
  179. url = base_url + "/jobinfo/stop";
  180. needFresh = true;
  181. } else if ("job_resume" == type) {
  182. typeName = I18n.jobinfo_opt_start ;
  183. url = base_url + "/jobinfo/start";
  184. needFresh = true;
  185. } else if ("job_del" == type) {
  186. typeName = I18n.system_opt_del ;
  187. url = base_url + "/jobinfo/remove";
  188. needFresh = true;
  189. } else {
  190. return;
  191. }
  192. var id = $(this).parent('p').attr("id");
  193. layer.confirm( I18n.system_ok + typeName + '?', {
  194. icon: 3,
  195. title: I18n.system_tips ,
  196. btn: [ I18n.system_ok, I18n.system_cancel ]
  197. }, function(index){
  198. layer.close(index);
  199. $.ajax({
  200. type : 'POST',
  201. url : url,
  202. data : {
  203. "id" : id
  204. },
  205. dataType : "json",
  206. success : function(data){
  207. if (data.code == 200) {
  208. layer.msg( typeName + I18n.system_success );
  209. if (needFresh) {
  210. //window.location.reload();
  211. jobTable.fnDraw(false);
  212. }
  213. } else {
  214. layer.msg( data.msg || typeName + I18n.system_fail );
  215. }
  216. }
  217. });
  218. });
  219. });
  220. // job trigger
  221. $("#job_list").on('click', '.job_trigger',function() {
  222. var id = $(this).parent('p').attr("id");
  223. var row = tableData['key'+id];
  224. $("#jobTriggerModal .form input[name='id']").val( row.id );
  225. $("#jobTriggerModal .form textarea[name='executorParam']").val( row.executorParam );
  226. $('#jobTriggerModal').modal({backdrop: false, keyboard: false}).modal('show');
  227. });
  228. $("#jobTriggerModal .ok").on('click',function() {
  229. $.ajax({
  230. type : 'POST',
  231. url : base_url + "/jobinfo/trigger",
  232. data : {
  233. "id" : $("#jobTriggerModal .form input[name='id']").val(),
  234. "executorParam" : $("#jobTriggerModal .textarea[name='executorParam']").val()
  235. },
  236. dataType : "json",
  237. success : function(data){
  238. if (data.code == 200) {
  239. $('#jobTriggerModal').modal('hide');
  240. layer.msg( I18n.jobinfo_opt_run + I18n.system_success );
  241. } else {
  242. layer.msg( data.msg || I18n.jobinfo_opt_run + I18n.system_fail );
  243. }
  244. }
  245. });
  246. });
  247. $("#jobTriggerModal").on('hide.bs.modal', function () {
  248. $("#jobTriggerModal .form")[0].reset();
  249. });
  250. // add
  251. $(".add").click(function(){
  252. $('#addModal').modal({backdrop: false, keyboard: false}).modal('show');
  253. });
  254. var addModalValidate = $("#addModal .form").validate({
  255. errorElement : 'span',
  256. errorClass : 'help-block',
  257. focusInvalid : true,
  258. rules : {
  259. jobDesc : {
  260. required : true,
  261. maxlength: 50
  262. },
  263. jobCron : {
  264. required : true
  265. },
  266. author : {
  267. required : true
  268. },
  269. executorTimeout : {
  270. digits:true
  271. },
  272. executorFailRetryCount : {
  273. digits:true
  274. }
  275. },
  276. messages : {
  277. jobDesc : {
  278. required : I18n.system_please_input + I18n.jobinfo_field_jobdesc
  279. },
  280. jobCron : {
  281. required : I18n.system_please_input + "Cron"
  282. },
  283. author : {
  284. required : I18n.system_please_input + I18n.jobinfo_field_author
  285. },
  286. executorTimeout : {
  287. digits: I18n.system_please_input + I18n.system_digits
  288. },
  289. executorFailRetryCount : {
  290. digits: I18n.system_please_input + I18n.system_digits
  291. }
  292. },
  293. highlight : function(element) {
  294. $(element).closest('.form-group').addClass('has-error');
  295. },
  296. success : function(label) {
  297. label.closest('.form-group').removeClass('has-error');
  298. label.remove();
  299. },
  300. errorPlacement : function(error, element) {
  301. element.parent('div').append(error);
  302. },
  303. submitHandler : function(form) {
  304. // process
  305. var executorTimeout = $("#addModal .form input[name='executorTimeout']").val();
  306. if(!/^\d+$/.test(executorTimeout)) {
  307. executorTimeout = 0;
  308. }
  309. $("#addModal .form input[name='executorTimeout']").val(executorTimeout);
  310. var executorFailRetryCount = $("#addModal .form input[name='executorFailRetryCount']").val();
  311. if(!/^\d+$/.test(executorFailRetryCount)) {
  312. executorFailRetryCount = 0;
  313. }
  314. $("#addModal .form input[name='executorFailRetryCount']").val(executorFailRetryCount);
  315. $.post(base_url + "/jobinfo/add", $("#addModal .form").serialize(), function(data, status) {
  316. if (data.code == "200") {
  317. $('#addModal').modal('hide');
  318. layer.open({
  319. title: I18n.system_tips ,
  320. btn: [ I18n.system_ok ],
  321. content: I18n.system_add_suc ,
  322. icon: '1',
  323. end: function(layero, index){
  324. jobTable.fnDraw();
  325. //window.location.reload();
  326. }
  327. });
  328. } else {
  329. layer.open({
  330. title: I18n.system_tips ,
  331. btn: [ I18n.system_ok ],
  332. content: (data.msg || I18n.system_add_fail),
  333. icon: '2'
  334. });
  335. }
  336. });
  337. }
  338. });
  339. $("#addModal").on('hide.bs.modal', function () {
  340. $("#addModal .form")[0].reset();
  341. addModalValidate.resetForm();
  342. $("#addModal .form .form-group").removeClass("has-error");
  343. $(".remote_panel").show(); // remote
  344. $("#addModal .form input[name='executorHandler']").removeAttr("readonly");
  345. });
  346. // glueType change
  347. $(".glueType").change(function(){
  348. // executorHandler
  349. var $executorHandler = $(this).parents("form").find("input[name='executorHandler']");
  350. var glueType = $(this).val();
  351. if ('BEAN' != glueType) {
  352. $executorHandler.val("");
  353. $executorHandler.attr("readonly","readonly");
  354. } else {
  355. $executorHandler.removeAttr("readonly");
  356. }
  357. });
  358. $("#addModal .glueType").change(function(){
  359. // glueSource
  360. var glueType = $(this).val();
  361. if ('GLUE_GROOVY'==glueType){
  362. $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_java").val() );
  363. } else if ('GLUE_SHELL'==glueType){
  364. $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_shell").val() );
  365. } else if ('GLUE_PYTHON'==glueType){
  366. $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_python").val() );
  367. } else if ('GLUE_PHP'==glueType){
  368. $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_php").val() );
  369. } else if ('GLUE_NODEJS'==glueType){
  370. $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_nodejs").val() );
  371. } else if ('GLUE_POWERSHELL'==glueType){
  372. $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_powershell").val() );
  373. } else {
  374. $("#addModal .form textarea[name='glueSource']").val("");
  375. }
  376. });
  377. // update
  378. $("#job_list").on('click', '.update',function() {
  379. var id = $(this).parent('p').attr("id");
  380. var row = tableData['key'+id];
  381. // base data
  382. $("#updateModal .form input[name='id']").val( row.id );
  383. $('#updateModal .form select[name=jobGroup] option[value='+ row.jobGroup +']').prop('selected', true);
  384. $("#updateModal .form input[name='jobDesc']").val( row.jobDesc );
  385. $("#updateModal .form input[name='jobCron']").val( row.jobCron );
  386. $("#updateModal .form input[name='author']").val( row.author );
  387. $("#updateModal .form input[name='alarmEmail']").val( row.alarmEmail );
  388. $("#updateModal .form input[name='executorTimeout']").val( row.executorTimeout );
  389. $("#updateModal .form input[name='executorFailRetryCount']").val( row.executorFailRetryCount );
  390. $('#updateModal .form select[name=executorRouteStrategy] option[value='+ row.executorRouteStrategy +']').prop('selected', true);
  391. $("#updateModal .form input[name='executorHandler']").val( row.executorHandler );
  392. $("#updateModal .form textarea[name='executorParam']").val( row.executorParam );
  393. $("#updateModal .form input[name='childJobId']").val( row.childJobId );
  394. $('#updateModal .form select[name=executorBlockStrategy] option[value='+ row.executorBlockStrategy +']').prop('selected', true);
  395. $('#updateModal .form select[name=glueType] option[value='+ row.glueType +']').prop('selected', true);
  396. $("#updateModal .form select[name=glueType]").change();
  397. // show
  398. $('#updateModal').modal({backdrop: false, keyboard: false}).modal('show');
  399. });
  400. var updateModalValidate = $("#updateModal .form").validate({
  401. errorElement : 'span',
  402. errorClass : 'help-block',
  403. focusInvalid : true,
  404. rules : {
  405. jobDesc : {
  406. required : true,
  407. maxlength: 50
  408. },
  409. jobCron : {
  410. required : true
  411. },
  412. author : {
  413. required : true
  414. },
  415. executorTimeout : {
  416. digits:true
  417. },
  418. executorFailRetryCount : {
  419. digits:true
  420. }
  421. },
  422. messages : {
  423. jobDesc : {
  424. required : I18n.system_please_input + I18n.jobinfo_field_jobdesc
  425. },
  426. jobCron : {
  427. required : I18n.system_please_input + "Cron"
  428. },
  429. author : {
  430. required : I18n.system_please_input + I18n.jobinfo_field_author
  431. },
  432. executorTimeout : {
  433. digits: I18n.system_please_input + I18n.system_digits
  434. },
  435. executorFailRetryCount : {
  436. digits: I18n.system_please_input + I18n.system_digits
  437. }
  438. },
  439. highlight : function(element) {
  440. $(element).closest('.form-group').addClass('has-error');
  441. },
  442. success : function(label) {
  443. label.closest('.form-group').removeClass('has-error');
  444. label.remove();
  445. },
  446. errorPlacement : function(error, element) {
  447. element.parent('div').append(error);
  448. },
  449. submitHandler : function(form) {
  450. // process
  451. var executorTimeout = $("#updateModal .form input[name='executorTimeout']").val();
  452. if(!/^\d+$/.test(executorTimeout)) {
  453. executorTimeout = 0;
  454. }
  455. $("#updateModal .form input[name='executorTimeout']").val(executorTimeout);
  456. var executorFailRetryCount = $("#updateModal .form input[name='executorFailRetryCount']").val();
  457. if(!/^\d+$/.test(executorFailRetryCount)) {
  458. executorFailRetryCount = 0;
  459. }
  460. $("#updateModal .form input[name='executorFailRetryCount']").val(executorFailRetryCount);
  461. // post
  462. $.post(base_url + "/jobinfo/update", $("#updateModal .form").serialize(), function(data, status) {
  463. if (data.code == "200") {
  464. $('#updateModal').modal('hide');
  465. layer.open({
  466. title: I18n.system_tips ,
  467. btn: [ I18n.system_ok ],
  468. content: I18n.system_update_suc ,
  469. icon: '1',
  470. end: function(layero, index){
  471. //window.location.reload();
  472. jobTable.fnDraw();
  473. }
  474. });
  475. } else {
  476. layer.open({
  477. title: I18n.system_tips ,
  478. btn: [ I18n.system_ok ],
  479. content: (data.msg || I18n.system_update_fail ),
  480. icon: '2'
  481. });
  482. }
  483. });
  484. }
  485. });
  486. $("#updateModal").on('hide.bs.modal', function () {
  487. $("#updateModal .form")[0].reset()
  488. });
  489. /**
  490. * find title by name, GlueType
  491. */
  492. function findGlueTypeTitle(glueType) {
  493. var glueTypeTitle;
  494. $("#addModal .form select[name=glueType] option").each(function () {
  495. var name = $(this).val();
  496. var title = $(this).text();
  497. if (glueType == name) {
  498. glueTypeTitle = title;
  499. return false
  500. }
  501. });
  502. return glueTypeTitle;
  503. }
  504. });