浏览代码

定时任务新增立即执行一次功能
定时任务新增立即执行一次功能

Zetting 6 年之前
父节点
当前提交
a07d9ad44a

+ 12 - 11
src/main/java/com/ifast/common/config/Constant.java

@@ -6,35 +6,36 @@ package com.ifast.common.config;
  * <small> 2018年4月6日 | Aron</small>
  */
 public class Constant {
-    
+
     /**
      * <pre>
      * </pre>
      * <small> 2018年4月6日 | Aron</small>
      */
-    public static class Job{
+    public static class Job {
         // 停止计划任务
         public static String STATUS_RUNNING_STOP = "stop";
         // 开启计划任务
         public static String STATUS_RUNNING_START = "start";
-        
-    } 
-    
+
+
+    }
+
     /**
      * <pre>
      * </pre>
      * <small> 2018年4月6日 | Aron</small>
      */
-    public static class Generator{
+    public static class Generator {
         // 自动去除表前缀
         public static String AUTO_REOMVE_PRE = "true";
-        
-    } 
-    
-    public static class Sys{
+
+    }
+
+    public static class Sys {
         // 部门根节点id
         public static Long DEPT_ROOT_ID = 0L;
     }
-   
+
 
 }

+ 19 - 6
src/main/java/com/ifast/job/controller/JobController.java

@@ -19,7 +19,7 @@ import java.util.Arrays;
  * <pre>
  * 定时任务
  * </pre>
- * 
+ *
  * <small> 2018年3月23日 | Aron</small>
  */
 @Controller
@@ -27,13 +27,13 @@ import java.util.Arrays;
 public class JobController extends AdminBaseController {
     @Autowired
     private JobService taskScheduleJobService;
-    
+
     @Log("进入定时任务管理页面")
     @GetMapping()
     String taskScheduleJob() {
         return "common/job/job";
     }
-    
+
     @Log("查询定时任务列表")
     @ResponseBody
     @GetMapping("/list")
@@ -43,13 +43,13 @@ public class JobController extends AdminBaseController {
         Page<TaskDO> page = taskScheduleJobService.selectPage(getPage(TaskDO.class), wrapper);
         return Result.ok(page);
     }
-    
+
     @Log("进入定时任务添加页面")
     @GetMapping("/add")
     String add() {
         return "common/job/add";
     }
-    
+
     @Log("进入定时任务编辑页面")
     @GetMapping("/edit/{id}")
     String edit(@PathVariable("id") Long id, Model model) {
@@ -112,7 +112,7 @@ public class JobController extends AdminBaseController {
 
         return Result.ok();
     }
-    
+
     @Log("根据id和cmd执行/停止定时任务")
     @PostMapping(value = "/changeJobStatus")
     @ResponseBody
@@ -132,4 +132,17 @@ public class JobController extends AdminBaseController {
         return Result.ok("任务" + label + "失败");
     }
 
+    @Log("立即执行一次任务")
+    @PostMapping(value = "/runNowOnce")
+    @ResponseBody
+    public Result<String> runNowOnce(Long id) {
+        try {
+            taskScheduleJobService.runNowOnce(id);
+            return Result.ok("任务执行成功");
+        } catch (Exception e) {
+           log.error("执行任务失败",e);
+        }
+        return Result.ok("任务执行失败");
+    }
+
 }

+ 2 - 0
src/main/java/com/ifast/job/service/JobService.java

@@ -19,4 +19,6 @@ public interface JobService extends CoreService<TaskDO> {
 	void changeStatus(Long jobId, String cmd) throws SchedulerException;
 
 	void updateCron(Long jobId) throws SchedulerException;
+
+	void runNowOnce(Long jobId)  throws SchedulerException ;
 }

+ 9 - 0
src/main/java/com/ifast/job/service/impl/JobServiceImpl.java

@@ -99,4 +99,13 @@ public class JobServiceImpl extends CoreServiceImpl<TaskDao, TaskDO> implements
         updateById(scheduleJob);
     }
 
+    @Override
+    public void runNowOnce(Long jobId) throws SchedulerException {
+        TaskDO scheduleJob = selectById(jobId);
+        if (scheduleJob == null) {
+            return;
+        }
+        quartzManager.runAJobNow(ScheduleJobUtils.entityToData(scheduleJob));
+    }
+
 }

+ 31 - 0
src/main/java/com/ifast/tags/IftgDialectEntrance.java

@@ -0,0 +1,31 @@
+package com.ifast.tags;
+
+import com.ifast.tags.processor.IftgSelectProcessor;
+import org.springframework.stereotype.Component;
+import org.thymeleaf.processor.IProcessor;
+import org.thymeleaf.spring4.dialect.SpringStandardDialect;
+
+import java.util.HashSet;
+import java.util.Set;
+
+
+/**
+ * 自定注解处理入口
+ *
+ * @author: zet
+ * @date:2018/8/22
+ */
+@Component
+public class IftgDialectEntrance extends SpringStandardDialect {
+    public String getPrefix() {
+        return "iftg";
+    }
+
+    @Override
+    public Set<IProcessor> getProcessors() {
+        final Set<IProcessor> processors = new HashSet<IProcessor>();
+        //<iftg:select/> 注解
+        processors.add(new IftgSelectProcessor());
+        return processors;
+    }
+}

+ 136 - 0
src/main/java/com/ifast/tags/processor/IftgSelectProcessor.java

@@ -0,0 +1,136 @@
+package com.ifast.tags.processor;
+
+import com.ifast.common.service.DictService;
+import com.ifast.tags.util.IftgUtil;
+import com.ifast.tags.vo.ValueVo;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.context.ApplicationContext;
+import org.thymeleaf.Arguments;
+import org.thymeleaf.dom.Attribute;
+import org.thymeleaf.dom.Element;
+import org.thymeleaf.dom.Node;
+import org.thymeleaf.dom.Text;
+import org.thymeleaf.processor.element.AbstractMarkupSubstitutionElementProcessor;
+import org.thymeleaf.spring4.context.SpringWebContext;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * select 注解
+ * 用法
+ * <iftg:select dicType = "dic_of_sex"></iftg:select>
+ * 属性 dicType是必填项
+ * --情况1:当dicType = 字典中的type 时select下拉数值渲染的value
+ *  为字典中的name字段,name 为字典中的name字段
+ *
+ *
+ * --情况2:当dicType = all时候表示select下拉数值渲染的value
+ *  为字典中的type字段,name 为字典中的description字段)
+ *
+ * 注:
+ *   控件的其他属性,用户可根据需求完全自定义,如需要加上name属性和Id属性则
+ *   <iftg:select dicType = "dic_of_sex" name="mySelect" id="selectId"></iftg:select>
+ * @author: zet
+ * @date:2018/8/22
+ */
+public class IftgSelectProcessor extends AbstractMarkupSubstitutionElementProcessor {
+    private DictService dictService;
+    private boolean firstLoad = true;
+
+    public IftgSelectProcessor() {
+        super("select");
+    }
+
+    /**
+     * 核心处理
+     *
+     * @param arguments thymeleaf 上下文对象
+     * @param element   当前节点对象
+     * @return
+     */
+    @Override
+    protected List<Node> getMarkupSubstitutes(Arguments arguments, Element element) {
+        //初始化
+        init(arguments);
+
+        //获取值
+        String dicType = element.getAttributeValue("dicType");//字典类型
+        String defaultValue = element.getAttributeValue("defaultValue");//默认选中
+
+        String thValue = IftgUtil.getTargetAttributeValue(arguments, element, "th:value");//回显值
+        String defaultSelect = StringUtils.isNoneBlank(thValue) ? thValue : defaultValue;
+        List<ValueVo> valueVos = IftgUtil.getValues(dictService, dicType, new String[]{defaultSelect});
+
+        //set 值
+        List<Node> nodes = null;
+
+        //创建对象
+        Element selectEle = createSelect(element.getAttributeMap(), valueVos);
+        nodes = new ArrayList<>();
+        nodes.add(selectEle);
+
+        return nodes;
+    }
+
+    /**
+     * 初始化
+     *
+     * @param argument
+     */
+    private void init(Arguments argument) {
+        if (firstLoad) {
+            ApplicationContext appCtx = ((SpringWebContext) argument.getContext()).getApplicationContext();
+            dictService = appCtx.getBean(DictService.class);
+            firstLoad = false;
+        }
+    }
+
+    /**
+     * 创建select对象
+     *
+     * @param attributeMap select 属性值
+     * @param options      下拉值
+     * @return
+     */
+    private Element createSelect(Map<String, Attribute> attributeMap, List<ValueVo> options) {
+        Element selectEle = new Element("select");
+        Element optionEle = new Element("option");
+        optionEle.setAttribute("style", "display: none");
+        selectEle.addChild(optionEle);
+
+        //创建option
+        for (ValueVo option : options) {
+            optionEle = new Element("option");
+            optionEle.setAttribute("value", option.getVlaue());
+
+            //默认选中
+            if (Objects.nonNull(option.getSelected())
+                    && option.getSelected()) {
+                optionEle.setAttribute("selected", "selected");
+            }
+
+            optionEle.addChild(new Text(option.getName()));
+            selectEle.addChild(optionEle);
+        }
+
+
+        //创建属性
+        if (Objects.nonNull(attributeMap)) {
+            for (String mapKey : attributeMap.keySet()) {
+                String key = mapKey;
+                String value = attributeMap.get(key).getValue();
+                selectEle.setAttribute(key, value);
+            }
+        }
+
+        return selectEle;
+    }
+
+    @Override
+    public int getPrecedence() {
+        return 1000;
+    }
+}

+ 129 - 0
src/main/java/com/ifast/tags/util/IftgUtil.java

@@ -0,0 +1,129 @@
+package com.ifast.tags.util;
+
+import com.ifast.common.domain.DictDO;
+import com.ifast.common.service.DictService;
+import com.ifast.tags.vo.ValueVo;
+import org.thymeleaf.Arguments;
+import org.thymeleaf.Configuration;
+import org.thymeleaf.dom.Element;
+import org.thymeleaf.standard.expression.IStandardExpression;
+import org.thymeleaf.standard.expression.IStandardExpressionParser;
+import org.thymeleaf.standard.expression.StandardExpressions;
+
+import java.util.*;
+
+/**
+ * IftgUtil 辅助工具类
+ *
+ * @author: zet
+ * @date: 2018/8/23 22:46
+ */
+public class IftgUtil {
+    private static final String KEY_ALL = "all";
+
+    /**
+     * 获取数据
+     *
+     * @param dictService 字典service对象
+     * @param dicType     字典类型编码
+     * @return
+     */
+    public static List<ValueVo> getValues(DictService dictService, String dicType) {
+        return getValues(dictService, dicType, null);
+    }
+
+    /**
+     * 获取数据
+     *
+     * @param dictService   字典service对象
+     * @param dicType       字典类型编码
+     * @param selectedValue 默认选中的值
+     * @return
+     */
+    public static List<ValueVo> getValues(DictService dictService, String dicType, String[] selectedValue) {
+        if (KEY_ALL.contains(dicType)) {
+            return getListType(dictService, dicType, selectedValue);
+        }
+
+        Map<String, Object> map = new HashMap<>(16);
+        map.put("type", dicType);
+        List<DictDO> dictDOS = dictService.selectByMap(map);
+        List<ValueVo> options = parseToValues(dictDOS, selectedValue);
+        return options;
+    }
+
+    public static List<ValueVo> getListType(DictService dictService, String dicType, String[] selectedValue) {
+        List<DictDO> dictDOS = dictService.listType();
+        return parseListTypeToValues(dictDOS, selectedValue);
+    }
+
+    /**
+     * 获取标签对应值
+     *
+     * @param arguments     thymeleaf 上下文对象
+     * @param element       当前节点对象
+     * @param attributeName 属性名
+     * @return 标签对象值
+     */
+    public static String getTargetAttributeValue(Arguments arguments, Element element, String attributeName) {
+        String attributeValue = element.getAttributeValue(attributeName);
+        Configuration configuration = arguments.getConfiguration();
+        IStandardExpressionParser expressionParser = StandardExpressions.getExpressionParser(configuration);
+        IStandardExpression expression = null;
+        try {
+            expression = expressionParser.parseExpression(configuration, arguments, attributeValue);
+        } catch (Exception e) {
+            return null;
+        }
+        Object result = expression.execute(configuration, arguments);
+        return result == null ? "" : result.toString();
+    }
+
+    /**
+     * 转换格式
+     *
+     * @param dictDOS 待转换的字典数据
+     * @return 转换后的格式
+     */
+    private static List<ValueVo> parseToValues(List<DictDO> dictDOS, String[] selectedValue) {
+        List<ValueVo> valueVos = new ArrayList<>();
+        ValueVo valueVo = null;
+        List<String> selecteds = Objects.nonNull(selectedValue) ? Arrays.asList(selectedValue) : null;
+
+        for (DictDO dictDO : dictDOS) {
+            valueVo = new ValueVo();
+            valueVo.setName(dictDO.getName());
+            valueVo.setVlaue(dictDO.getValue());
+            if (Objects.nonNull(selecteds) &&
+                    selecteds.contains(dictDO.getValue())) {
+                valueVo.setSelected(true);
+            }
+            valueVos.add(valueVo);
+        }
+        return valueVos;
+    }
+
+    /**
+     * 转换格式(字典大类字典)
+     *
+     * @param dictDOS 待转换的字典数据
+     * @return 转换后的格式
+     */
+    private static List<ValueVo> parseListTypeToValues(List<DictDO> dictDOS, String[] selectedValue) {
+        List<ValueVo> valueVos = new ArrayList<>();
+        ValueVo valueVo = null;
+        List<String> selecteds = Objects.nonNull(selectedValue) ? Arrays.asList(selectedValue) : null;
+
+        for (DictDO dictDO : dictDOS) {
+            valueVo = new ValueVo();
+            valueVo.setName(dictDO.getDescription());
+            valueVo.setVlaue(dictDO.getType());
+            if (Objects.nonNull(selecteds) &&
+                    selecteds.contains(dictDO.getType())) {
+                valueVo.setSelected(true);
+            }
+            valueVos.add(valueVo);
+        }
+        return valueVos;
+    }
+}

+ 27 - 0
src/main/java/com/ifast/tags/vo/ValueVo.java

@@ -0,0 +1,27 @@
+package com.ifast.tags.vo;
+
+import lombok.Data;
+
+/**
+ * 控件数值vo
+ *
+ * @author: zet
+ * @date:2018/8/22
+ */
+@Data
+public class ValueVo {
+    /**
+     * value值
+     */
+    private String vlaue;
+
+    /**
+     * 显示名称
+     */
+    private String name;
+
+    /**
+     * 是否选中
+     */
+    private Boolean selected;
+}

+ 14 - 27
src/main/resources/static/js/appjs/common/dict/dict.js

@@ -23,33 +23,20 @@ $(function() {
 	load();
 });
 function selectLoad() {
-	var html = "";
-	$.ajax({
-		url : '/common/sysDict/type',
-		success : function(data) {
-			//加载数据
-			for (var i = 0; i < data.length; i++) {
-				console.log(data[i])
-				html += '<option value="' + data[i].type + '">' + data[i].description + '</option>'
-			}
-			console.log(html)
-			$(".chosen-select").append(html);
-			$(".chosen-select").chosen({
-				maxHeight : 200
-			});
-			//点击事件
-			$('.chosen-select').on('change', function(e, params) {
-				console.log(params.selected);
-				var opt = {
-					query : {
-						type : params.selected,
-						name : $('#searchName').val()
-					}
-				}
-				$('#exampleTable').bootstrapTable('refresh', opt);
-			});
-		}
-	});
+    $(".chosen-select").chosen({
+        maxHeight : 200
+    });
+    //点击事件
+    $('.chosen-select').on('change', function(e, params) {
+        console.log(params.selected);
+        var opt = {
+            query : {
+                type : params.selected,
+                name : $('#searchName').val()
+            }
+        }
+        $('#exampleTable').bootstrapTable('refresh', opt);
+    });
 }
 function load() {
 	selectLoad();

+ 283 - 254
src/main/resources/static/js/appjs/common/job/job.js

@@ -1,283 +1,312 @@
 var prefix = "/common/job"
-$(function() {
-	load();
+$(function () {
+    load();
 });
 
 function load() {
-	$('#exampleTable')
-			.bootstrapTable(
-					{
-						method : 'get', // 服务器数据的请求方式 get or post
-						url : prefix + "/list", // 服务器数据的加载地址
-						// showRefresh : true,
-						// showToggle : true,
-						// showColumns : true,
-						iconSize : 'outline',
-						toolbar : '#exampleToolbar',
-						striped : true, // 设置为true会有隔行变色效果
-						dataType : "json", // 服务器返回的数据类型
-						pagination : true, // 设置为true会在底部显示分页条
-						singleSelect : false, // 设置为true将禁止多选
-						// contentType : "application/x-www-form-urlencoded",
-						// //发送到服务器的数据编码类型
-						pageSize : 10, // 如果设置了分页,每页数据条数
-						pageNumber : 1, // 如果设置了分布,首页页码
-						// search : true, // 是否显示搜索框
-						showColumns : false, // 是否显示内容下拉框(选择显示的列)
-						sidePagination : "server", // 设置在哪里进行分页,可选值为"client" 或者
-						// "server"
-						queryParamsType : "",
-						// //设置为limit则会发送符合RESTFull格式的参数
-						queryParams : function(params) {
-							return {
-								// 说明:传入后台的参数包括offset开始索引,limit步长,sort排序列,order:desc或者,以及所有列的键值对
-								pageNumber : params.pageNumber,
-								pageSize : params.pageSize
-							// name:$('#searchName').val(),
-							// username:$('#searchName').val()
-							};
-						},
-						// //请求服务器数据时,你可以通过重写参数的方式添加一些额外的参数,例如 toolbar 中的参数 如果
-						// queryParamsType = 'limit' ,返回参数必须包含
-						// limit, offset, search, sort, order 否则, 需要包含:
-						// pageSize, pageNumber, searchText, sortName,
-						// sortOrder.
-						// 返回false将会终止请求
-						responseHandler : function(res) {
-							console.log(res);
-							return {
-								"total" : res.data.total,// 总数
-								"rows" : res.data.records
-							// 数据
-							};
-						},
-						columns : [
-								{
-									checkbox : true
-								},
-								{
-									field : 'id',
-									title : 'id'
-								},
-								{
-									field : 'jobName',
-									title : '任务名称'
-								},
-								{
-									field : 'jobGroup',
-									title : '任务分组'
-								},
-								{
-									field : 'beanClass',
-									title : '任务类'
-								},
-								{
-									field : 'cronExpression',
-									title : 'cron表达式'
-								},
-								{
-									visible : false,
-									field : 'methodName',
-									title : '方法名称'
-								},
-								{
-									visible : false,
-									field : 'isConcurrent',
-									title : '任务是否有状态'
-								},
-								{
-									visible : false,
-									field : 'description',
-									title : '任务描述'
-								},
-								{
-									visible : false,
-									field : 'updateBy',
-									title : '更新者'
-								},
+    $('#exampleTable')
+        .bootstrapTable(
+            {
+                method: 'get', // 服务器数据的请求方式 get or post
+                url: prefix + "/list", // 服务器数据的加载地址
+                // showRefresh : true,
+                // showToggle : true,
+                // showColumns : true,
+                iconSize: 'outline',
+                toolbar: '#exampleToolbar',
+                striped: true, // 设置为true会有隔行变色效果
+                dataType: "json", // 服务器返回的数据类型
+                pagination: true, // 设置为true会在底部显示分页条
+                singleSelect: false, // 设置为true将禁止多选
+                // contentType : "application/x-www-form-urlencoded",
+                // //发送到服务器的数据编码类型
+                pageSize: 10, // 如果设置了分页,每页数据条数
+                pageNumber: 1, // 如果设置了分布,首页页码
+                // search : true, // 是否显示搜索框
+                showColumns: false, // 是否显示内容下拉框(选择显示的列)
+                sidePagination: "server", // 设置在哪里进行分页,可选值为"client" 或者
+                // "server"
+                queryParamsType: "",
+                // //设置为limit则会发送符合RESTFull格式的参数
+                queryParams: function (params) {
+                    return {
+                        // 说明:传入后台的参数包括offset开始索引,limit步长,sort排序列,order:desc或者,以及所有列的键值对
+                        pageNumber: params.pageNumber,
+                        pageSize: params.pageSize
+                        // name:$('#searchName').val(),
+                        // username:$('#searchName').val()
+                    };
+                },
+                // //请求服务器数据时,你可以通过重写参数的方式添加一些额外的参数,例如 toolbar 中的参数 如果
+                // queryParamsType = 'limit' ,返回参数必须包含
+                // limit, offset, search, sort, order 否则, 需要包含:
+                // pageSize, pageNumber, searchText, sortName,
+                // sortOrder.
+                // 返回false将会终止请求
+                responseHandler: function (res) {
+                    console.log(res);
+                    return {
+                        "total": res.data.total,// 总数
+                        "rows": res.data.records
+                        // 数据
+                    };
+                },
+                columns: [
+                    {
+                        checkbox: true
+                    },
+                    {
+                        field: 'id',
+                        title: 'id'
+                    },
+                    {
+                        field: 'jobName',
+                        title: '任务名称'
+                    },
+                    {
+                        field: 'jobGroup',
+                        title: '任务分组'
+                    },
+                    {
+                        field: 'beanClass',
+                        title: '任务类'
+                    },
+                    {
+                        field: 'cronExpression',
+                        title: 'cron表达式'
+                    },
+                    {
+                        visible: false,
+                        field: 'methodName',
+                        title: '方法名称'
+                    },
+                    {
+                        visible: false,
+                        field: 'isConcurrent',
+                        title: '任务是否有状态'
+                    },
+                    {
+                        visible: false,
+                        field: 'description',
+                        title: '任务描述'
+                    },
+                    {
+                        visible: false,
+                        field: 'updateBy',
+                        title: '更新者'
+                    },
 
-								{
-									visible : false,
-									field : 'createDate',
-									title : '创建时间'
-								},
+                    {
+                        visible: false,
+                        field: 'createDate',
+                        title: '创建时间'
+                    },
 
-								{
-									visible : false,
-									field : 'updateDate',
-									title : '更新时间'
-								},
-								{
-									visible : false,
-									field : 'createBy',
-									title : '创建者'
-								},
-								{
-									visible : false,
-									field : 'springBean',
-									title : 'Spring bean'
-								},
+                    {
+                        visible: false,
+                        field: 'updateDate',
+                        title: '更新时间'
+                    },
+                    {
+                        visible: false,
+                        field: 'createBy',
+                        title: '创建者'
+                    },
+                    {
+                        visible: false,
+                        field: 'springBean',
+                        title: 'Spring bean'
+                    },
 
-								{
-									field : 'jobStatus',
-									title : '停起操作',
-									formatter : function(value, row, index) {
-										var e = '<a class="btn btn-success btn-xs" href="#" mce_href="#" title="点击开启" onclick="changeStatus(\''
-												+ row.id
-												+ '\',\''
-												+ row.jobStatus
-												+ '\')"><i class="fa fa-hourglass-start"></i>开启</a> ';
-										var f = '<a class="btn btn-danger btn-xs" href="#" mce_href="#" title="点击关闭" onclick="changeStatus(\''
-												+ row.id
-												+ '\',\''
-												+ row.jobStatus
-												+ '\')"><i class="fa fa-square-o">关闭</i></a> ';
-										if (row.jobStatus == 0) {
-											return e;
-										} else {
-											return f;
-										}
+                    {
+                        field: 'jobStatus',
+                        title: '停起操作',
+                        formatter: function (value, row, index) {
+                            var e = '<a class="btn btn-success btn-xs" href="#" mce_href="#" title="点击开启" onclick="changeStatus(\''
+                                + row.id
+                                + '\',\''
+                                + row.jobStatus
+                                + '\')"><i class="fa fa-hourglass-start"></i>开启</a> ';
+                            var f = '<a class="btn btn-danger btn-xs" href="#" mce_href="#" title="点击关闭" onclick="changeStatus(\''
+                                + row.id
+                                + '\',\''
+                                + row.jobStatus
+                                + '\')"><i class="fa fa-square-o">关闭</i></a> ';
+                            if (row.jobStatus == 0) {
+                                return e;
+                            } else {
+                                return f;
+                            }
 
-									}
-								},
+                        }
+                    },
 
-								{
-									title : '操作',
-									field : 'id',
-									align : 'center',
-									formatter : function(value, row, index) {
-										var e = '<a class="btn btn-primary btn-sm" href="#" mce_href="#" title="编辑" onclick="edit(\''
-												+ row.id
-												+ '\',\''
-												+ row.jobStatus
-												+ '\')"><i class="fa fa-edit"></i></a> ';
-										var d = '<a class="btn btn-warning btn-sm" href="#" title="删除"  mce_href="#" onclick="remove(\''
-												+ row.id
-												+ '\')"><i class="fa fa-remove"></i></a> ';
-										var f = '<a class="btn btn-success btn-sm" href="#" title="开启"  mce_href="#" onclick="resetPwd(\''
-												+ row.id
-												+ '\')"><i class="fa fa-key"></i></a> ';
-										return e + d;
-									}
-								} ]
-					});
+                    {
+                        title: '操作',
+                        field: 'id',
+                        align: 'center',
+                        formatter: function (value, row, index) {
+                            var e = '<a class="btn btn-primary btn-sm" href="#" mce_href="#" title="编辑" onclick="edit(\''
+                                + row.id
+                                + '\',\''
+                                + row.jobStatus
+                                + '\')"><i class="fa fa-edit"></i></a> ';
+                            var d = '<a class="btn btn-warning btn-sm" href="#" title="删除"  mce_href="#" onclick="remove(\''
+                                + row.id
+                                + '\')"><i class="fa fa-remove"></i></a> ';
+                            var f = '<a class="btn btn-success btn-sm" href="#" title="立即执行一次"  mce_href="#" onclick="runNowOnce(\''
+                                + row.id
+                                + '\',\''
+                                + row.jobStatus
+                                + '\')"><i class="fa fa-bolt"></i></a> ';
+                            return e + d + f;
+                        }
+                    }]
+            });
 }
 
 function reLoad() {
-	$('#exampleTable').bootstrapTable('refresh');
+    $('#exampleTable').bootstrapTable('refresh');
 }
 
 function add() {
-	layer.open({
-		type : 2,
-		title : '增加',
-		maxmin : true,
-		shadeClose : false, // 点击遮罩关闭层
-		area : [ '800px', '520px' ],
-		content : prefix + '/add' // iframe的url
-	});
+    layer.open({
+        type: 2,
+        title: '增加',
+        maxmin: true,
+        shadeClose: false, // 点击遮罩关闭层
+        area: ['800px', '520px'],
+        content: prefix + '/add' // iframe的url
+    });
 }
 
 function edit(id, status) {
-	if (status == '1') {
-		layer.alert('修改之前请先停止任务');
-		return;
-	}
-	layer.open({
-		type : 2,
-		title : '编辑',
-		maxmin : true,
-		shadeClose : false, // 点击遮罩关闭层
-		area : [ '800px', '520px' ],
-		content : prefix + '/edit/' + id // iframe的url
-	});
+    if (status == '1') {
+        layer.alert('修改之前请先停止任务');
+        return;
+    }
+    layer.open({
+        type: 2,
+        title: '编辑',
+        maxmin: true,
+        shadeClose: false, // 点击遮罩关闭层
+        area: ['800px', '520px'],
+        content: prefix + '/edit/' + id // iframe的url
+    });
 }
 
 function remove(id) {
-	layer.confirm('确定要删除选中的记录?', {
-		btn : [ '确定', '取消' ]
-	}, function() {
-		$.ajax({
-			url : prefix + "/remove",
-			type : "post",
-			data : {
-				'id' : id
-			},
-			success : function(r) {
-				if (r.code == 0) {
-					layer.msg(r.msg);
-					reLoad();
-				} else {
-					layer.msg(r.msg);
-				}
-			}
-		});
-	})
+    layer.confirm('确定要删除选中的记录?', {
+        btn: ['确定', '取消']
+    }, function () {
+        $.ajax({
+            url: prefix + "/remove",
+            type: "post",
+            data: {
+                'id': id
+            },
+            success: function (r) {
+                if (r.code == 0) {
+                    layer.msg(r.msg);
+                    reLoad();
+                } else {
+                    layer.msg(r.msg);
+                }
+            }
+        });
+    })
 }
 
 function changeStatus(id, status) {
-	var actCh;
-	var cmd;
-	if (status == 0) {
-		cmd = 'start';
-		actCh = "确认要开启任务吗?";
-	} else {
-		cmd = 'stop';
-		actCh = "确认要停止任务吗?";
-	}
-	layer.confirm(actCh, {
-		btn : [ '确定', '取消' ]
-	}, function() {
-		$.ajax({
-			url : prefix + "/changeJobStatus",
-			type : "post",
-			data : {
-				'id' : id,
-				'cmd' : cmd
-			},
-			success : function(r) {
-				if (r.code == 0) {
-					layer.msg(r.msg);
-					reLoad();
-				} else {
-					layer.msg(r.msg);
-				}
-			}
-		});
-	})
+    var actCh;
+    var cmd;
+    if (status == 0) {
+        cmd = 'start';
+        actCh = "确认要开启任务吗?";
+    } else {
+        cmd = 'stop';
+        actCh = "确认要停止任务吗?";
+    }
+    layer.confirm(actCh, {
+        btn: ['确定', '取消']
+    }, function () {
+        $.ajax({
+            url: prefix + "/changeJobStatus",
+            type: "post",
+            data: {
+                'id': id,
+                'cmd': cmd
+            },
+            success: function (r) {
+                if (r.code == 0) {
+                    layer.msg(r.msg);
+                    reLoad();
+                } else {
+                    layer.msg(r.msg);
+                }
+            }
+        });
+    })
 }
 
 function batchRemove() {
-	var rows = $('#exampleTable').bootstrapTable('getSelections'); // 返回所有选择的行,当没有选择的记录时,返回一个空数组
-	if (rows.length == 0) {
-		layer.msg("请选择要删除的数据");
-		return;
-	}
-	layer.confirm("确认要删除选中的'" + rows.length + "'条数据吗?", {
-		btn : [ '确定', '取消' ]
-	// 按钮
-	}, function() {
-		var ids = new Array();
-		// 遍历所有选择的行数据,取每条数据对应的ID
-		$.each(rows, function(i, row) {
-			ids[i] = row['id'];
-		});
-		$.ajax({
-			type : 'POST',
-			data : {
-				"ids" : ids
-			},
-			url : prefix + '/batchRemove',
-			success : function(r) {
-				if (r.code == 0) {
-					layer.msg(r.msg);
-					reLoad();
-				} else {
-					layer.msg(r.msg);
-				}
-			}
-		});
-	}, function() {
+    var rows = $('#exampleTable').bootstrapTable('getSelections'); // 返回所有选择的行,当没有选择的记录时,返回一个空数组
+    if (rows.length == 0) {
+        layer.msg("请选择要删除的数据");
+        return;
+    }
+    layer.confirm("确认要删除选中的'" + rows.length + "'条数据吗?", {
+        btn: ['确定', '取消']
+        // 按钮
+    }, function () {
+        var ids = new Array();
+        // 遍历所有选择的行数据,取每条数据对应的ID
+        $.each(rows, function (i, row) {
+            ids[i] = row['id'];
+        });
+        $.ajax({
+            type: 'POST',
+            data: {
+                "ids": ids
+            },
+            url: prefix + '/batchRemove',
+            success: function (r) {
+                if (r.code == 0) {
+                    layer.msg(r.msg);
+                    reLoad();
+                } else {
+                    layer.msg(r.msg);
+                }
+            }
+        });
+    }, function () {
 
-	});
+    });
+}
+
+function runNowOnce(id, status) {
+    if (status == 0) {
+        layer.msg("任务状态必须是开启中才可执行");
+        return;
+    }
+
+    layer.confirm("确认要执行任务吗", {
+        btn: ['确定', '取消']
+    }, function () {
+        $.ajax({
+            url: prefix + "/runNowOnce",
+            type: "post",
+            data: {
+                'id': id
+            },
+            success: function (r) {
+                if (r.code == 0) {
+                    layer.msg(r.msg);
+                    reLoad();
+                } else {
+                    layer.msg(r.msg);
+                }
+            }
+        });
+    })
 }

+ 5 - 2
src/main/resources/templates/common/sysDict/add.html

@@ -51,8 +51,11 @@
 							<div class="form-group">
 								<label class="col-sm-3 control-label">删除标记:</label>
 								<div class="col-sm-8">
-									<input id="delFlag" name="delFlag" class="form-control"
-										type="text">
+									<!--<input id="delFlag" name="delFlag" class="form-control"-->
+										<!--type="text">-->
+									<iftg:select dicType="del_flag" class="form-control" defaultValue="0"
+												 tabindex="2" style="width: 100%">
+									</iftg:select>
 								</div>
 							</div>
 							<div class="form-group">

+ 92 - 88
src/main/resources/templates/common/sysDict/edit.html

@@ -1,88 +1,92 @@
-<!DOCTYPE html>
-<html>
-<meta charset="utf-8">
-<head th:include="include :: header"></head>
-<body class="gray-bg">
-<div class="wrapper wrapper-content ">
-    <div class="row">
-        <div class="col-sm-12">
-            <div class="ibox float-e-margins">
-                <div class="ibox-content">
-                    <form class="form-horizontal m-t" id="signupForm">
-                        <input id="id" name="id" th:value="${sysDict.id}"
-                               class="form-control" type="hidden">
-                        <div class="form-group">
-                            <label class="col-sm-3 control-label">标签名:</label>
-                            <div class="col-sm-8">
-                                <input id="name" name="name" th:value="${sysDict.name}"
-                                       class="form-control" type="text">
-                            </div>
-                        </div>
-                        <div class="form-group">
-                            <label class="col-sm-3 control-label">数据值:</label>
-                            <div class="col-sm-8">
-                                <input id="value" name="value" th:value="${sysDict.value}"
-                                       class="form-control" type="text">
-                            </div>
-                        </div>
-                        <div class="form-group">
-                            <label class="col-sm-3 control-label">类型:</label>
-                            <div class="col-sm-8">
-                                <input id="type" name="type" th:value="${sysDict.type}"
-                                       class="form-control" type="text">
-                            </div>
-                        </div>
-                        <div class="form-group">
-                            <label class="col-sm-3 control-label">描述:</label>
-                            <div class="col-sm-8">
-                                <input id="description" name="description"
-                                       th:value="${sysDict.description}" class="form-control"
-                                       type="text">
-                            </div>
-                        </div>
-                        <div class="form-group">
-                            <label class="col-sm-3 control-label">排序:</label>
-                            <div class="col-sm-8">
-                                <input id="sort" name="sort" th:value="${sysDict.sort}"
-                                       class="form-control" type="text">
-                            </div>
-                        </div>
-                        <div class="form-group hidden">
-                            <label class="col-sm-3 control-label ">父级编号:</label>
-                            <div class="col-sm-8">
-                                <input id="parentId" name="parentId"
-                                       th:value="${sysDict.parentId}" class="form-control"
-                                       type="text">
-                            </div>
-                        </div>
-
-                        <div class="form-group">
-                            <label class="col-sm-3 control-label">备注信息:</label>
-                            <div class="col-sm-8">
-                                <input id="remarks" name="remarks"
-                                       th:value="${sysDict.remarks}" class="form-control" type="text">
-                            </div>
-                        </div>
-                        <div class="form-group">
-                            <label class="col-sm-3 control-label">删除标记:</label>
-                            <div class="col-sm-8">
-                                <input id="delFlag" name="delFlag"
-                                       th:value="${sysDict.delFlag}" class="form-control" type="text">
-                            </div>
-                        </div>
-                        <div class="form-group">
-                            <div class="col-sm-8 col-sm-offset-3">
-                                <button type="submit" class="btn btn-primary">提交</button>
-                            </div>
-                        </div>
-                    </form>
-                </div>
-            </div>
-        </div>
-    </div>
-</div>
-<div th:include="include::footer"></div>
-<script type="text/javascript" src="/js/appjs/common/dict/edit.js">
-</script>
-</body>
-</html>
+<!DOCTYPE html>
+<html>
+<meta charset="utf-8">
+<head th:include="include :: header"></head>
+<body class="gray-bg">
+<div class="wrapper wrapper-content ">
+    <div class="row">
+        <div class="col-sm-12">
+            <div class="ibox float-e-margins">
+                <div class="ibox-content">
+                    <form class="form-horizontal m-t" id="signupForm">
+                        <input id="id" name="id" th:value="${sysDict.id}"
+                               class="form-control" type="hidden">
+                        <div class="form-group">
+                            <label class="col-sm-3 control-label">标签名:</label>
+                            <div class="col-sm-8">
+                                <input id="name" name="name" th:value="${sysDict.name}"
+                                       class="form-control" type="text">
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label class="col-sm-3 control-label">数据值:</label>
+                            <div class="col-sm-8">
+                                <input id="value" name="value" th:value="${sysDict.value}"
+                                       class="form-control" type="text">
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label class="col-sm-3 control-label">类型:</label>
+                            <div class="col-sm-8">
+                                <input id="type" name="type" th:value="${sysDict.type}"
+                                       class="form-control" type="text">
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label class="col-sm-3 control-label">描述:</label>
+                            <div class="col-sm-8">
+                                <input id="description" name="description"
+                                       th:value="${sysDict.description}" class="form-control"
+                                       type="text">
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label class="col-sm-3 control-label">排序:</label>
+                            <div class="col-sm-8">
+                                <input id="sort" name="sort" th:value="${sysDict.sort}"
+                                       class="form-control" type="text">
+                            </div>
+                        </div>
+                        <div class="form-group hidden">
+                            <label class="col-sm-3 control-label ">父级编号:</label>
+                            <div class="col-sm-8">
+                                <input id="parentId" name="parentId"
+                                       th:value="${sysDict.parentId}" class="form-control"
+                                       type="text">
+                            </div>
+                        </div>
+
+                        <div class="form-group">
+                            <label class="col-sm-3 control-label">备注信息:</label>
+                            <div class="col-sm-8">
+                                <input id="remarks" name="remarks"
+                                       th:value="${sysDict.remarks}" class="form-control" type="text">
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label class="col-sm-3 control-label">删除标记:</label>
+                            <div class="col-sm-8">
+                                <iftg:select dicType="del_flag" class="form-control"
+                                             th:value="${sysDict.delFlag}"
+                                             tabindex="2" style="width: 100%">
+                                </iftg:select>
+                                <!--<input id="delFlag" name="delFlag"-->
+                                       <!--th:value="${sysDict.delFlag}" class="form-control" type="text">-->
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <div class="col-sm-8 col-sm-offset-3">
+                                <button type="submit" class="btn btn-primary">提交</button>
+                            </div>
+                        </div>
+                    </form>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<div th:include="include::footer"></div>
+<script type="text/javascript" src="/js/appjs/common/dict/edit.js">
+</script>
+</body>
+</html>

+ 3 - 3
src/main/resources/templates/common/sysDict/sysDict.html

@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html xmlns:iftg="http://www.w3.org/1999/xhtml">
 <meta charset="utf-8">
 <head th:include="include :: header"></head>
 <body class="gray-bg">
@@ -26,10 +26,10 @@
 								placeholder="请输入标签">
 						</div>
 						<div class="columns pull-right col-md-2 nopadding">
-							<select data-placeholder="选择类别" class="form-control chosen-select"
+							<iftg:select dicType="all" data-placeholder="选择类别" class="form-control chosen-select"
 								tabindex="2" style="width: 100%">
 								<option value="">选择类别</option>
-							</select>
+							</iftg:select>
 						</div>
 					</div>
 					<table id="exampleTable" data-mobile-responsive="true">