From b8850e6b821590ea34c16bf16bb63b16153927e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AE=E6=9C=8B?= Date: Fri, 7 Oct 2022 17:21:04 +0800 Subject: [PATCH] =?UTF-8?q?feature:=E6=96=B0=E5=A2=9E=20job=20=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=E5=AF=BC=E5=87=BA=E5=8A=9F=E8=83=BD\Added=20the=20Job?= =?UTF-8?q?=20import=20and=20export=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controller/JobInfoController.java | 70 ++++++++++++--- .../admin/core/model/XxlJobInfoImport.java | 27 ++++++ .../com/xxl/job/admin/dao/XxlJobGroupDao.java | 23 +++++ .../com/xxl/job/admin/dao/XxlJobInfoDao.java | 21 ++++- .../xxl/job/admin/service/XxlJobService.java | 25 +++++- .../admin/service/impl/XxlJobServiceImpl.java | 86 ++++++++++++++++++- .../main/resources/i18n/message_en.properties | 7 ++ .../resources/i18n/message_zh_CN.properties | 9 +- .../resources/i18n/message_zh_TC.properties | 9 +- .../mybatis-mapper/XxlJobGroupMapper.xml | 25 +++++- .../mybatis-mapper/XxlJobInfoMapper.xml | 62 ++++++++++++- .../resources/static/js/jobinfo.index.1.js | 69 +++++++++++++++ .../templates/jobinfo/jobinfo.index.ftl | 71 ++++++++++++--- 13 files changed, 467 insertions(+), 37 deletions(-) create mode 100644 xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfoImport.java diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java index ea314b3239..066e78bd42 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java @@ -1,6 +1,5 @@ package com.xxl.job.admin.controller; -import com.xxl.job.admin.core.cron.CronExpression; import com.xxl.job.admin.core.exception.XxlJobException; import com.xxl.job.admin.core.model.XxlJobGroup; import com.xxl.job.admin.core.model.XxlJobInfo; @@ -19,6 +18,8 @@ import com.xxl.job.core.enums.ExecutorBlockStrategyEnum; import com.xxl.job.core.glue.GlueTypeEnum; import com.xxl.job.core.util.DateUtil; +import com.xxl.job.core.util.GsonTool; +import org.apache.tomcat.util.http.fileupload.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; @@ -26,11 +27,20 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; +import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; -import java.text.ParseException; -import java.util.*; +import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Map; /** * index controller @@ -45,7 +55,7 @@ public class JobInfoController { private XxlJobGroupDao xxlJobGroupDao; @Resource private XxlJobService xxlJobService; - + @RequestMapping public String index(HttpServletRequest request, Model model, @RequestParam(required = false, defaultValue = "-1") int jobGroup) { @@ -97,46 +107,78 @@ public static void validPermission(HttpServletRequest request, int jobGroup) { throw new RuntimeException(I18nUtil.getString("system_permission_limit") + "[username="+ loginUser.getUsername() +"]"); } } - + @RequestMapping("/pageList") @ResponseBody - public Map pageList(@RequestParam(required = false, defaultValue = "0") int start, + public Map pageList(@RequestParam(required = false, defaultValue = "0") int start, @RequestParam(required = false, defaultValue = "10") int length, int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author) { - + return xxlJobService.pageList(start, length, jobGroup, triggerStatus, jobDesc, executorHandler, author); } - + + @RequestMapping("/export") + @ResponseBody + public void export(HttpServletResponse response, @RequestParam(required = false, defaultValue = "0") int start, + @RequestParam(required = false, defaultValue = "100") int length, + int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author) { + + Map export = xxlJobService.export(start, length, jobGroup, triggerStatus, jobDesc, executorHandler, author); + String exportJson = GsonTool.toJson(export); + try(ServletOutputStream outputStream = response.getOutputStream()) { + response.setCharacterEncoding("utf-8"); + response.setHeader("Content-disposition", "attachment;filename=jobInfos.json"); + IOUtils.copyLarge(new ByteArrayInputStream(exportJson.getBytes(StandardCharsets.UTF_8)), outputStream); + } catch (IOException e) { + // reset response + response.reset(); + response.setContentType("application/json"); + response.setCharacterEncoding("utf-8"); + ReturnT returnT = new ReturnT<>(ReturnT.FAIL_CODE, (I18nUtil.getString("system_api_error"))); + try { + response.getWriter().println(GsonTool.toJson(returnT)); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + } + + @RequestMapping("/import") + @ResponseBody + public ReturnT jobImport(MultipartFile file, String importStrategy) { + return xxlJobService.jobImport(file, importStrategy); + } + @RequestMapping("/add") @ResponseBody public ReturnT add(XxlJobInfo jobInfo) { return xxlJobService.add(jobInfo); } - + @RequestMapping("/update") @ResponseBody public ReturnT update(XxlJobInfo jobInfo) { return xxlJobService.update(jobInfo); } - + @RequestMapping("/remove") @ResponseBody public ReturnT remove(int id) { return xxlJobService.remove(id); } - + @RequestMapping("/stop") @ResponseBody public ReturnT pause(int id) { return xxlJobService.stop(id); } - + @RequestMapping("/start") @ResponseBody public ReturnT start(int id) { return xxlJobService.start(id); } - + @RequestMapping("/trigger") @ResponseBody //@PermissionLimit(limit = false) @@ -176,5 +218,5 @@ public ReturnT> nextTriggerTime(String scheduleType, String schedul return new ReturnT>(result); } - + } diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfoImport.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfoImport.java new file mode 100644 index 0000000000..ec6d29b000 --- /dev/null +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfoImport.java @@ -0,0 +1,27 @@ +package com.xxl.job.admin.core.model; + +import java.util.List; + +/** + * @author acton + */ +public class XxlJobInfoImport { + private List jobGroups; + private List jobInfos; + + public List getJobGroups() { + return jobGroups; + } + + public void setJobGroups(List jobGroups) { + this.jobGroups = jobGroups; + } + + public List getJobInfos() { + return jobInfos; + } + + public void setJobInfos(List jobInfos) { + this.jobInfos = jobInfos; + } +} diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobGroupDao.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobGroupDao.java index b608d9fbc0..5eb273042e 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobGroupDao.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobGroupDao.java @@ -4,6 +4,7 @@ import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; +import java.util.Collection; import java.util.List; /** @@ -34,4 +35,26 @@ public int pageListCount(@Param("offset") int offset, @Param("appname") String appname, @Param("title") String title); + /** + * load batch by ids + * + * @param jobGroupIds + * @return + */ + List loadByIds(@Param("jobGroupIds") Collection jobGroupIds); + + /** + * removeAll + * + * @return + */ + int removeAll(); + + /** + * saveWithId + * + * @param jobGroup + * @return + */ + int saveWithId(XxlJobGroup jobGroup); } diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobInfoDao.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobInfoDao.java index d640efffec..076c8ab584 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobInfoDao.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobInfoDao.java @@ -28,13 +28,13 @@ public int pageListCount(@Param("offset") int offset, @Param("jobDesc") String jobDesc, @Param("executorHandler") String executorHandler, @Param("author") String author); - + public int save(XxlJobInfo info); public XxlJobInfo loadById(@Param("id") int id); - + public int update(XxlJobInfo xxlJobInfo); - + public int delete(@Param("id") long id); public List getJobsByGroup(@Param("jobGroup") int jobGroup); @@ -45,5 +45,18 @@ public int pageListCount(@Param("offset") int offset, public int scheduleUpdate(XxlJobInfo xxlJobInfo); - + /** + * deleteAll + * + * @return + */ + int deleteAll(); + + /** + * saveWithId + * + * @param jobInfo + * @return + */ + int saveWithId(XxlJobInfo jobInfo); } diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/service/XxlJobService.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/service/XxlJobService.java index 61da3a27c7..1172592dcb 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/service/XxlJobService.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/service/XxlJobService.java @@ -3,13 +3,14 @@ import com.xxl.job.admin.core.model.XxlJobInfo; import com.xxl.job.core.biz.model.ReturnT; +import org.springframework.web.multipart.MultipartFile; import java.util.Date; import java.util.Map; /** * core job action for xxl-job - * + * * @author xuxueli 2016-5-28 15:30:33 */ public interface XxlJobService { @@ -83,4 +84,26 @@ public interface XxlJobService { */ public ReturnT> chartInfo(Date startDate, Date endDate); + /** + * export job + * + * @param start + * @param length + * @param jobGroup + * @param triggerStatus + * @param jobDesc + * @param executorHandler + * @param author + * @return + */ + Map export(int start, int length, int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author); + + /** + * import job + * + * @param file + * @param importStrategy + * @return + */ + ReturnT jobImport(MultipartFile file, String importStrategy); } diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java index 530ee41c89..ea6eaf0761 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java @@ -3,6 +3,7 @@ import com.xxl.job.admin.core.cron.CronExpression; import com.xxl.job.admin.core.model.XxlJobGroup; import com.xxl.job.admin.core.model.XxlJobInfo; +import com.xxl.job.admin.core.model.XxlJobInfoImport; import com.xxl.job.admin.core.model.XxlJobLogReport; import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum; import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum; @@ -15,13 +16,17 @@ import com.xxl.job.core.enums.ExecutorBlockStrategyEnum; import com.xxl.job.core.glue.GlueTypeEnum; import com.xxl.job.core.util.DateUtil; +import com.xxl.job.core.util.GsonTool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; +import java.io.IOException; import java.text.MessageFormat; import java.util.*; +import java.util.stream.Collectors; /** * core job action for xxl-job @@ -41,14 +46,14 @@ public class XxlJobServiceImpl implements XxlJobService { private XxlJobLogGlueDao xxlJobLogGlueDao; @Resource private XxlJobLogReportDao xxlJobLogReportDao; - + @Override public Map pageList(int start, int length, int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author) { // page list List list = xxlJobInfoDao.pageList(start, length, jobGroup, triggerStatus, jobDesc, executorHandler, author); int list_count = xxlJobInfoDao.pageListCount(start, length, jobGroup, triggerStatus, jobDesc, executorHandler, author); - + // package result Map maps = new HashMap(); maps.put("recordsTotal", list_count); // 总记录数 @@ -431,4 +436,81 @@ public ReturnT> chartInfo(Date startDate, Date endDate) { return new ReturnT>(result); } + @Override + public Map export(int start, int length, int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author) { + Map exportJob = new HashMap<>(16); + int total = xxlJobInfoDao.pageListCount(start, length, jobGroup, triggerStatus, jobDesc, executorHandler, author); + if (total <= 0) { + return exportJob; + } + List exportJobList = new ArrayList<>(total); + int pageCount = total % length == 0 ? total / length : total / length + 1; + for (int i = 0; i < pageCount; i++) { + start = i == 0 ? 0 : length * i + 1; + List xxlJobInfos = xxlJobInfoDao.pageList(start, length, jobGroup, triggerStatus, jobDesc, executorHandler, author); + exportJobList.addAll(xxlJobInfos); + } + Set jobGroupIds = exportJobList.stream().map(XxlJobInfo::getJobGroup).collect(Collectors.toSet()); + List jobGroups = xxlJobGroupDao.loadByIds(jobGroupIds); + exportJob.put("jobGroups", jobGroups); + exportJob.put("jobInfos", exportJobList); + return exportJob; + } + + @Override + public ReturnT jobImport(MultipartFile file, String importStrategy) { + String filename = file.getOriginalFilename(); + if (filename == null || !filename.endsWith(".json")) { + return new ReturnT<>(ReturnT.FAIL_CODE, I18nUtil.getString("job_info_import_valid")); + } + String context = "{}"; + try { + context = new String(file.getBytes()); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + XxlJobInfoImport xxlJobInfoImport = GsonTool.fromJson(context, XxlJobInfoImport.class); + List jobGroups = xxlJobInfoImport.getJobGroups(); + List jobInfos = xxlJobInfoImport.getJobInfos(); + if (jobGroups == null || jobGroups.isEmpty()) { + return new ReturnT<>(ReturnT.FAIL_CODE, "jobGroups" + I18nUtil.getString("system_not_found")); + } + if (jobInfos == null || jobInfos.isEmpty()) { + return new ReturnT<>(ReturnT.FAIL_CODE, "jobInfos" + I18nUtil.getString("system_not_found")); + } + + if ("overwrite".equals(importStrategy)) { + xxlJobGroupDao.removeAll(); + for (XxlJobGroup jobGroup : jobGroups) { + xxlJobGroupDao.saveWithId(jobGroup); + } + xxlJobInfoDao.deleteAll(); + for (XxlJobInfo jobInfo : jobInfos) { + xxlJobInfoDao.saveWithId(jobInfo); + } + } else { + for (XxlJobGroup jobGroup : jobGroups) { + jobGroup.setUpdateTime(new Date()); + XxlJobGroup group = xxlJobGroupDao.load(jobGroup.getId()); + if (group == null) { + xxlJobGroupDao.save(jobGroup); + } else { + xxlJobGroupDao.update(jobGroup); + } + } + for (XxlJobInfo jobInfo : jobInfos) { + jobInfo.setUpdateTime(new Date()); + jobInfo.setGlueUpdatetime(new Date()); + XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(jobInfo.getId()); + if (xxlJobInfo == null) { + jobInfo.setAddTime(new Date()); + xxlJobInfoDao.save(jobInfo); + } else { + xxlJobInfoDao.update(jobInfo); + } + } + } + return ReturnT.SUCCESS; + } + } diff --git a/xxl-job-admin/src/main/resources/i18n/message_en.properties b/xxl-job-admin/src/main/resources/i18n/message_en.properties index 2e91fd6934..fe526e09ae 100644 --- a/xxl-job-admin/src/main/resources/i18n/message_en.properties +++ b/xxl-job-admin/src/main/resources/i18n/message_en.properties @@ -155,6 +155,13 @@ jobinfo_conf_base=Base configuration jobinfo_conf_schedule=Schedule configuration jobinfo_conf_job=Job configuration jobinfo_conf_advanced=Advanced configuration +job_info_import=Import +job_info_import_file=Import file +job_info_import_strategy=Import strategy +job_info_import_merge=merge +job_info_import_overwrite=overwrite +job_info_import_valid=The imported file format is incorrect +job_info_export=Export ## job log joblog_name=Trigger Log diff --git a/xxl-job-admin/src/main/resources/i18n/message_zh_CN.properties b/xxl-job-admin/src/main/resources/i18n/message_zh_CN.properties index 7891570df5..fe0f3fe1f5 100644 --- a/xxl-job-admin/src/main/resources/i18n/message_zh_CN.properties +++ b/xxl-job-admin/src/main/resources/i18n/message_zh_CN.properties @@ -155,6 +155,13 @@ jobinfo_conf_base=基础配置 jobinfo_conf_schedule=调度配置 jobinfo_conf_job=任务配置 jobinfo_conf_advanced=高级配置 +job_info_import=导入 +job_info_import_file=导入文件 +job_info_import_strategy=导入策略 +job_info_import_merge=合并 +job_info_import_overwrite=覆盖 +job_info_import_valid=导入文件格式不正确 +job_info_export=导出 ## job log joblog_name=调度日志 @@ -273,4 +280,4 @@ user_update_loginuser_limit=禁止操作当前登录账号 ## help job_help=使用教程 -job_help_document=官方文档 \ No newline at end of file +job_help_document=官方文档 diff --git a/xxl-job-admin/src/main/resources/i18n/message_zh_TC.properties b/xxl-job-admin/src/main/resources/i18n/message_zh_TC.properties index c61994d191..b288e34b90 100755 --- a/xxl-job-admin/src/main/resources/i18n/message_zh_TC.properties +++ b/xxl-job-admin/src/main/resources/i18n/message_zh_TC.properties @@ -155,6 +155,13 @@ jobinfo_conf_base=基礎配置 jobinfo_conf_schedule=調度配置 jobinfo_conf_job=任務配置 jobinfo_conf_advanced=高級配置 +job_info_import=導入 +job_info_import_file=導入文件 +job_info_import_strategy=導入策略 +job_info_import_merge=合并 +job_info_import_overwrite=覆蓋 +job_info_import_valid=導入文件格式不正確 +job_info_export=導出 ## job log joblog_name=調度日誌 @@ -273,4 +280,4 @@ user_update_loginuser_limit=禁止操作當前登入帳號 ## help job_help=使用教程 -job_help_document=官方文件 \ No newline at end of file +job_help_document=官方文件 diff --git a/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobGroupMapper.xml b/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobGroupMapper.xml index 87299f88ba..19f435944f 100644 --- a/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobGroupMapper.xml +++ b/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobGroupMapper.xml @@ -1,8 +1,8 @@ - - + @@ -88,4 +88,23 @@ - \ No newline at end of file + + + + DELETE FROM xxl_job_group + WHERE id is not null + + + + INSERT INTO xxl_job_group ( `id`, `app_name`, `title`, `address_type`, `address_list`, `update_time`) + values ( #{id}, #{appname}, #{title}, #{addressType}, #{addressList}, #{updateTime} ); + + + diff --git a/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml b/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml index 7b3c3a3ed3..e3db0597ba 100644 --- a/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml +++ b/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml @@ -237,4 +237,64 @@ WHERE id = #{id} - \ No newline at end of file + + DELETE + FROM xxl_job_info + WHERE id is not null + + + + INSERT INTO xxl_job_info ( + id, + job_group, + job_desc, + add_time, + update_time, + author, + alarm_email, + schedule_type, + schedule_conf, + misfire_strategy, + executor_route_strategy, + executor_handler, + executor_param, + executor_block_strategy, + executor_timeout, + executor_fail_retry_count, + glue_type, + glue_source, + glue_remark, + glue_updatetime, + child_jobid, + trigger_status, + trigger_last_time, + trigger_next_time + ) VALUES ( + #{id}, + #{jobGroup}, + #{jobDesc}, + #{addTime}, + #{updateTime}, + #{author}, + #{alarmEmail}, + #{scheduleType}, + #{scheduleConf}, + #{misfireStrategy}, + #{executorRouteStrategy}, + #{executorHandler}, + #{executorParam}, + #{executorBlockStrategy}, + #{executorTimeout}, + #{executorFailRetryCount}, + #{glueType}, + #{glueSource}, + #{glueRemark}, + #{glueUpdatetime}, + #{childJobId}, + #{triggerStatus}, + #{triggerLastTime}, + #{triggerNextTime} + ); + + + diff --git a/xxl-job-admin/src/main/resources/static/js/jobinfo.index.1.js b/xxl-job-admin/src/main/resources/static/js/jobinfo.index.1.js index b479e97247..877339c7a2 100644 --- a/xxl-job-admin/src/main/resources/static/js/jobinfo.index.1.js +++ b/xxl-job-admin/src/main/resources/static/js/jobinfo.index.1.js @@ -736,4 +736,73 @@ $(function() { $('#addModal').modal({backdrop: false, keyboard: false}).modal('show'); }); + // export + $("#export").click(function () { + $.ajax({ + type : 'POST', + url : base_url + "/jobinfo/export", + data : { + jobGroup : $('#jobGroup').val(), + triggerStatus : $('#triggerStatus').val(), + jobDesc : $('#jobDesc').val(), + executorHandler : $('#executorHandler').val(), + author : $('#author').val() + }, + responseType: 'blob', + success : function(data){ + if (data.code !== 500) { + let url = window.URL.createObjectURL(new Blob([data])); + let link = document.createElement('a') + link.style.display = 'none' + link.href = url + link.setAttribute('download', 'jobInfos.json') + document.body.appendChild(link) + link.click() + window.URL.revokeObjectURL(url) + document.body.removeChild(link) + } else { + layer.msg(data.msg || I18n.job_info_export + I18n.system_fail); + } + } + }); + }) + + // import + $("#import").click(function(){ + + $('#importModal').modal({backdrop: false, keyboard: false}).modal('show'); + }); + + $("#importModal").on('hide.bs.modal', function () { + $("#importModal .form")[0].reset(); + }); + + $("#importModal .import").on('click',function() { + $.ajax({ + type : 'POST', + url : base_url + "/jobinfo/import", + data : new FormData($("#importModal .form")[0]), + contentType: false, + processData: false, + success : function(data){ + if (data.code === 200) { + $('#importModal').modal('hide'); + layer.open({ + title: I18n.system_tips , + btn: [ I18n.system_ok ], + content: I18n.system_success , + icon: '1' + }); + jobTable.fnDraw(); + } else { + layer.open({ + title: I18n.system_tips , + btn: [ I18n.system_ok ], + content: (data.msg || I18n.system_fail ), + icon: '2' + }); + } + } + }); + }); }); diff --git a/xxl-job-admin/src/main/resources/templates/jobinfo/jobinfo.index.ftl b/xxl-job-admin/src/main/resources/templates/jobinfo/jobinfo.index.ftl index 3a5d7d8a7d..8b03f7c4f6 100644 --- a/xxl-job-admin/src/main/resources/templates/jobinfo/jobinfo.index.ftl +++ b/xxl-job-admin/src/main/resources/templates/jobinfo/jobinfo.index.ftl @@ -13,22 +13,23 @@ <@netCommon.commonHeader /> <@netCommon.commonLeft "jobinfo" /> - +

${I18n.jobinfo_name}

- +
- +
${I18n.jobinfo_field_jobgroup}
-
+
-
- +
+
+
+ +
+
+ +
+
+ +
+
+ +
-
-
- +
@@ -100,7 +111,7 @@
- + <@netCommon.commonFooter /> @@ -527,6 +538,46 @@ exit 0 +<#--Import--> + + <@netCommon.commonScript />