Bläddra i källkod

新增定时任务

zhouhao 8 år sedan
förälder
incheckning
7315e8be7a
27 ändrade filer med 2473 tillägg och 77 borttagningar
  1. 127 48
      hsweb-web-bean/src/main/java/org/hsweb/web/bean/po/quartz/QuartzJob.java
  2. 166 0
      hsweb-web-bean/src/main/java/org/hsweb/web/bean/po/quartz/QuartzJobHistory.java
  3. 304 13
      hsweb-web-bean/src/main/resources/system/install/sql/h2/install.sql
  4. 177 1
      hsweb-web-bean/src/main/resources/system/install/sql/mysql/install.sql
  5. 228 12
      hsweb-web-bean/src/main/resources/system/install/sql/oracle/install.sql
  6. 84 0
      hsweb-web-controller/src/main/java/org/hsweb/web/controller/quartz/QuartzJobController.java
  7. 28 0
      hsweb-web-dao/hsweb-web-dao-api/src/main/java/org/hsweb/web/dao/quartz/QuartzJobHistoryMapper.java
  8. 28 0
      hsweb-web-dao/hsweb-web-dao-api/src/main/java/org/hsweb/web/dao/quartz/QuartzJobMapper.java
  9. 63 0
      hsweb-web-dao/hsweb-web-dao-mybatis/src/main/resources/org/hsweb/web/dao/impl/mybatis/mapper/mysql/quartz/QuartzJobHistoryMapper.xml
  10. 67 0
      hsweb-web-dao/hsweb-web-dao-mybatis/src/main/resources/org/hsweb/web/dao/impl/mybatis/mapper/mysql/quartz/QuartzJobMapper.xml
  11. 63 0
      hsweb-web-dao/hsweb-web-dao-mybatis/src/main/resources/org/hsweb/web/dao/impl/mybatis/mapper/oracle/quartz/QuartzJobHistoryMapper.xml
  12. 67 0
      hsweb-web-dao/hsweb-web-dao-mybatis/src/main/resources/org/hsweb/web/dao/impl/mybatis/mapper/oracle/quartz/QuartzJobMapper.xml
  13. 1 1
      hsweb-web-datasource/src/main/java/org/hsweb/web/datasource/dynamic/DynamicDataSourceServiceImpl.java
  14. 41 0
      hsweb-web-service/hsweb-web-service-api/src/main/java/org/hsweb/web/service/quartz/QuartzJobHistoryService.java
  15. 36 0
      hsweb-web-service/hsweb-web-service-api/src/main/java/org/hsweb/web/service/quartz/QuartzJobService.java
  16. 14 0
      hsweb-web-service/hsweb-web-service-simple/pom.xml
  17. 67 0
      hsweb-web-service/hsweb-web-service-simple/src/main/java/org/hsweb/web/service/impl/SchedulerAutoConfiguration.java
  18. 83 0
      hsweb-web-service/hsweb-web-service-simple/src/main/java/org/hsweb/web/service/impl/quartz/QuartzJobHistoryServiceImpl.java
  19. 223 0
      hsweb-web-service/hsweb-web-service-simple/src/main/java/org/hsweb/web/service/impl/quartz/QuartzJobServiceImpl.java
  20. 118 0
      hsweb-web-service/hsweb-web-service-simple/src/main/java/org/hsweb/web/service/impl/quartz/SimpleJob.java
  21. 75 0
      hsweb-web-service/hsweb-web-service-simple/src/main/java/org/hsweb/web/service/impl/quartz/SimpleJobFactory.java
  22. 0 1
      hsweb-web-service/hsweb-web-service-simple/src/test/java/org/hsweb/web/service/impl/AbstractTestCase.java
  23. 59 0
      hsweb-web-service/hsweb-web-service-simple/src/test/java/org/hsweb/web/service/impl/quartz/QuartzJobServiceImplTest.java
  24. 68 0
      hsweb-web-service/hsweb-web-service-simple/src/test/java/org/hsweb/web/service/impl/quartz/QuartzTests.java
  25. 33 0
      hsweb-web-service/hsweb-web-service-simple/src/test/java/org/hsweb/web/service/impl/quartz/TestJob.java
  26. 2 1
      hsweb-web-service/hsweb-web-service-simple/src/test/resources/application.yml
  27. 251 0
      hsweb-web-service/hsweb-web-service-simple/src/test/resources/h2.sql

+ 127 - 48
hsweb-web-bean/src/main/java/org/hsweb/web/bean/po/quartz/QuartzJob.java

@@ -1,107 +1,186 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package org.hsweb.web.bean.po.quartz;
 
 import org.hsweb.web.bean.po.GenericPo;
 
+/**
+ * 定时调度任务
+ * Created by hsweb-generator Sep 27, 2016 1:55:18 AM
+ */
 public class QuartzJob extends GenericPo<String> {
+    //任务名称
     private String name;
-
+    //备注
     private String remark;
-
+    //cron表达式
     private String cron;
-
-    private String script;
-
-    private String language = "groovy";
-
-    private boolean running;
-
+    //执行脚本
+    private String script = "groovy";
+    //脚本语言
+    private String  language;
+    //是否启用
     private boolean enabled;
-
-    private boolean ready;
-
-    private long lastRunningStartTime;
-
-    private long lastRunningEndTime;
-
-    private String lastResult;
-
+    //启动参数
+    private String  parameters;
+    //任务类型
+    private byte    type;
+
+    /**
+     * 获取 任务名称
+     *
+     * @return String 任务名称
+     */
     public String getName() {
-        return name;
+        return this.name;
     }
 
+    /**
+     * 设置 任务名称
+     *
+     * @param name 任务名称
+     */
     public void setName(String name) {
         this.name = name;
     }
 
+    /**
+     * 获取 备注
+     *
+     * @return String 备注
+     */
     public String getRemark() {
-        return remark;
+        return this.remark;
     }
 
+    /**
+     * 设置 备注
+     *
+     * @param remark 备注
+     */
     public void setRemark(String remark) {
         this.remark = remark;
     }
 
+    /**
+     * 获取 cron表达式
+     *
+     * @return String cron表达式
+     */
     public String getCron() {
-        return cron;
+        return this.cron;
     }
 
+    /**
+     * 设置 cron表达式
+     *
+     * @param cron cron表达式
+     */
     public void setCron(String cron) {
         this.cron = cron;
     }
 
+    /**
+     * 获取 执行脚本
+     *
+     * @return String 执行脚本
+     */
     public String getScript() {
-        return script;
+        return this.script;
     }
 
+    /**
+     * 设置 执行脚本
+     *
+     * @param script 执行脚本
+     */
     public void setScript(String script) {
         this.script = script;
     }
 
+    /**
+     * 获取 脚本语言
+     *
+     * @return String 脚本语言
+     */
     public String getLanguage() {
-        return language;
+        return this.language;
     }
 
+    /**
+     * 设置 脚本语言
+     *
+     * @param language 脚本语言
+     */
     public void setLanguage(String language) {
         this.language = language;
     }
 
-    public boolean isRunning() {
-        return running;
-    }
-
-    public void setRunning(boolean running) {
-        this.running = running;
-    }
-
+    /**
+     * 获取 是否启用
+     *
+     * @return long 是否启用
+     */
     public boolean isEnabled() {
         return enabled;
     }
 
+    /**
+     * 设置 是否启用
+     *
+     * @param enabled 是否启用
+     */
     public void setEnabled(boolean enabled) {
         this.enabled = enabled;
     }
 
-    public long getLastRunningStartTime() {
-        return lastRunningStartTime;
-    }
-
-    public void setLastRunningStartTime(long lastRunningStartTime) {
-        this.lastRunningStartTime = lastRunningStartTime;
-    }
-
-    public long getLastRunningEndTime() {
-        return lastRunningEndTime;
+    /**
+     * 获取 启动参数
+     *
+     * @return String 启动参数
+     */
+    public String getParameters() {
+        return this.parameters;
     }
 
-    public void setLastRunningEndTime(long lastRunningEndTime) {
-        this.lastRunningEndTime = lastRunningEndTime;
+    /**
+     * 设置 启动参数
+     *
+     * @param parameters 启动参数
+     */
+    public void setParameters(String parameters) {
+        this.parameters = parameters;
     }
 
-    public String getLastResult() {
-        return lastResult;
+    /**
+     * 获取 任务类型
+     *
+     * @return long 任务类型
+     */
+    public byte getType() {
+        return this.type;
     }
 
-    public void setLastResult(String lastResult) {
-        this.lastResult = lastResult;
+    /**
+     * 设置 任务类型
+     *
+     * @param type 任务类型
+     */
+    public void setType(byte type) {
+        this.type = type;
     }
-}
+}

+ 166 - 0
hsweb-web-bean/src/main/java/org/hsweb/web/bean/po/quartz/QuartzJobHistory.java

@@ -0,0 +1,166 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.bean.po.quartz;
+
+import org.hsweb.web.bean.po.GenericPo;
+
+/**
+ * 定时调度任务执行记录
+ * Created by hsweb-generator Sep 27, 2016 1:57:14 AM
+ */
+public class QuartzJobHistory extends GenericPo<String> {
+    //任务ID
+    private String         jobId;
+    //开始时间
+    private java.util.Date startTime;
+    //结束时间
+    private java.util.Date endTime;
+    //执行结果
+    private String         result;
+    //状态
+    private byte           status;
+
+    /**
+     * 获取 任务ID
+     *
+     * @return String 任务ID
+     */
+    public String getJobId() {
+        return this.jobId;
+    }
+
+    /**
+     * 设置 任务ID
+     *
+     * @param jobId 任务ID
+     */
+    public void setJobId(String jobId) {
+        this.jobId = jobId;
+    }
+
+    /**
+     * 获取 开始时间
+     *
+     * @return java.util.Date 开始时间
+     */
+    public java.util.Date getStartTime() {
+        return this.startTime;
+    }
+
+    /**
+     * 设置 开始时间
+     *
+     * @param startTime 开始时间
+     */
+    public void setStartTime(java.util.Date startTime) {
+        this.startTime = startTime;
+    }
+
+    /**
+     * 获取 结束时间
+     *
+     * @return java.util.Date 结束时间
+     */
+    public java.util.Date getEndTime() {
+        return this.endTime;
+    }
+
+    /**
+     * 设置 结束时间
+     *
+     * @param endTime 结束时间
+     */
+    public void setEndTime(java.util.Date endTime) {
+        this.endTime = endTime;
+    }
+
+    /**
+     * 获取 执行结果
+     *
+     * @return String 执行结果
+     */
+    public String getResult() {
+        return this.result;
+    }
+
+    /**
+     * 设置 执行结果
+     *
+     * @param result 执行结果
+     */
+    public void setResult(String result) {
+        this.result = result;
+    }
+
+    /**
+     * 获取 状态
+     *
+     * @return long 状态
+     */
+    public byte getStatus() {
+        return this.status;
+    }
+
+    /**
+     * 设置 状态
+     *
+     * @param status 状态
+     */
+    public void setStatus(byte status) {
+        this.status = status;
+    }
+
+    public Status getStatusInfo() {
+        return Status.fromValue(getStatus());
+    }
+
+    public enum Status {
+        RUNNING("运行中", (byte) 0),
+        SUCCESS("成功", (byte) 1),
+        FAIL("失败", (byte) -1),
+        UNKNOW("未知", (byte) -2);
+
+        private   String name;
+        protected byte   value;
+
+        Status(String name, byte value) {
+            this.name = name;
+            this.value = value;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public byte getValue() {
+            return value;
+        }
+
+        public static Status fromValue(byte value) {
+            switch (value) {
+                case 0:
+                    return RUNNING;
+                case 1:
+                    return SUCCESS;
+                case -1:
+                    return FAIL;
+                default:
+                    return UNKNOW;
+            }
+        }
+    }
+}

+ 304 - 13
hsweb-web-bean/src/main/resources/system/install/sql/h2/install.sql

@@ -251,7 +251,7 @@ CREATE TABLE "S_QUERY_PLAN" (
   "CONFIG"      CLOB,
   "SHARING"     NUMBER(4),
   "CREATOR_ID"  VARCHAR2(32)  NOT NULL,
-  "CREATE_DATE" DATETIME          NOT NULL
+  "CREATE_DATE" DATETIME      NOT NULL
 );
 COMMENT ON TABLE "S_QUERY_PLAN" IS '查询方案表';
 COMMENT ON COLUMN "S_QUERY_PLAN"."U_ID" IS '主键';
@@ -264,17 +264,17 @@ COMMENT ON COLUMN "S_QUERY_PLAN"."CREATE_DATE" IS '创建日期';
 
 CREATE TABLE S_DATA_SOURCE
 (
-  U_ID VARCHAR(32) PRIMARY KEY NOT NULL,
-  NAME VARCHAR(64) NOT NULL,
-  DRIVER VARCHAR(128) NOT NULL,
-  URL VARCHAR(512) NOT NULL,
-  USERNAME VARCHAR(128) NOT NULL,
-  PASSWORD VARCHAR(128) NOT NULL,
-  ENABLED DECIMAL(4) NOT NULL,
-  CREATE_DATE DATE NOT NULL,
-  PROPERTIES CLOB,
-  COMMENT VARCHAR(512),
-  TEST_SQL VARCHAR(512)
+  U_ID        VARCHAR(32) PRIMARY KEY NOT NULL,
+  NAME        VARCHAR(64)             NOT NULL,
+  DRIVER      VARCHAR(128)            NOT NULL,
+  URL         VARCHAR(512)            NOT NULL,
+  USERNAME    VARCHAR(128)            NOT NULL,
+  PASSWORD    VARCHAR(128)            NOT NULL,
+  ENABLED     DECIMAL(4)              NOT NULL,
+  CREATE_DATE DATE                    NOT NULL,
+  PROPERTIES  CLOB,
+  COMMENT     VARCHAR(512),
+  TEST_SQL    VARCHAR(512)
 );
 COMMENT ON COLUMN S_DATA_SOURCE.U_ID IS 'ID';
 COMMENT ON COLUMN S_DATA_SOURCE.NAME IS '数据源名称';
@@ -311,4 +311,295 @@ ALTER TABLE "S_SCRIPT"
 ALTER TABLE "S_USER"
   ADD PRIMARY KEY ("U_ID");
 ALTER TABLE "S_USER_ROLE"
-  ADD PRIMARY KEY ("U_ID");
+  ADD PRIMARY KEY ("U_ID");
+
+--定时任务
+CREATE TABLE S_QUARTZ_JOB_HIS (
+  u_id       VARCHAR(32) NOT NULL  PRIMARY KEY,
+  job_id     VARCHAR(32) NOT NULL,
+  start_time DATETIME    NOT NULL,
+  end_time   DATETIME,
+  result     CLOB,
+  status     NUMBER(4)
+);
+COMMENT ON COLUMN S_QUARTZ_JOB_HIS.u_id IS '主键';
+COMMENT ON COLUMN S_QUARTZ_JOB_HIS.job_id IS '任务ID';
+COMMENT ON COLUMN S_QUARTZ_JOB_HIS.start_time IS '开始时间';
+COMMENT ON COLUMN S_QUARTZ_JOB_HIS.end_time IS '结束时间';
+COMMENT ON COLUMN S_QUARTZ_JOB_HIS.result IS '执行结果';
+COMMENT ON COLUMN S_QUARTZ_JOB_HIS.status IS '状态';
+
+
+CREATE TABLE S_QUARTZ_JOB (
+  u_id       VARCHAR(32)  NOT NULL PRIMARY KEY,
+  name       VARCHAR(128) NOT NULL,
+  remark     VARCHAR(512),
+  cron       VARCHAR(512) NOT NULL,
+  script     CLOB         NOT NULL,
+  language   VARCHAR(32)  NOT NULL,
+  enabled    NUMBER(4),
+  parameters CLOB,
+  type       NUMBER(4)
+);
+COMMENT ON COLUMN S_QUARTZ_JOB.u_id IS '主键';
+COMMENT ON COLUMN S_QUARTZ_JOB.name IS '任务名称';
+COMMENT ON COLUMN S_QUARTZ_JOB.remark IS '备注';
+COMMENT ON COLUMN S_QUARTZ_JOB.cron IS 'cron表达式';
+COMMENT ON COLUMN S_QUARTZ_JOB.script IS '执行脚本';
+COMMENT ON COLUMN S_QUARTZ_JOB.language IS '脚本语言';
+COMMENT ON COLUMN S_QUARTZ_JOB.enabled IS '是否启用';
+COMMENT ON COLUMN S_QUARTZ_JOB.parameters IS '启动参数';
+COMMENT ON COLUMN S_QUARTZ_JOB.type IS '任务类型';
+
+
+CREATE TABLE QRTZ_CALENDARS (
+  SCHED_NAME    VARCHAR(120) NOT NULL,
+  CALENDAR_NAME VARCHAR(200) NOT NULL,
+  CALENDAR      IMAGE        NOT NULL
+);
+
+CREATE TABLE QRTZ_CRON_TRIGGERS (
+  SCHED_NAME      VARCHAR(120) NOT NULL,
+  TRIGGER_NAME    VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP   VARCHAR(200) NOT NULL,
+  CRON_EXPRESSION VARCHAR(120) NOT NULL,
+  TIME_ZONE_ID    VARCHAR(80)
+);
+
+CREATE TABLE QRTZ_FIRED_TRIGGERS (
+  SCHED_NAME        VARCHAR(120) NOT NULL,
+  ENTRY_ID          VARCHAR(95)  NOT NULL,
+  TRIGGER_NAME      VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP     VARCHAR(200) NOT NULL,
+  INSTANCE_NAME     VARCHAR(200) NOT NULL,
+  FIRED_TIME        BIGINT       NOT NULL,
+  SCHED_TIME        BIGINT       NOT NULL,
+  PRIORITY          INTEGER      NOT NULL,
+  STATE             VARCHAR(16)  NOT NULL,
+  JOB_NAME          VARCHAR(200) NULL,
+  JOB_GROUP         VARCHAR(200) NULL,
+  IS_NONCONCURRENT  BOOLEAN      NULL,
+  REQUESTS_RECOVERY BOOLEAN      NULL
+);
+
+CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
+  SCHED_NAME    VARCHAR(120) NOT NULL,
+  TRIGGER_GROUP VARCHAR(200) NOT NULL
+);
+
+CREATE TABLE QRTZ_SCHEDULER_STATE (
+  SCHED_NAME        VARCHAR(120) NOT NULL,
+  INSTANCE_NAME     VARCHAR(200) NOT NULL,
+  LAST_CHECKIN_TIME BIGINT       NOT NULL,
+  CHECKIN_INTERVAL  BIGINT       NOT NULL
+);
+
+CREATE TABLE QRTZ_LOCKS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  LOCK_NAME  VARCHAR(40)  NOT NULL
+);
+
+CREATE TABLE QRTZ_JOB_DETAILS (
+  SCHED_NAME        VARCHAR(120) NOT NULL,
+  JOB_NAME          VARCHAR(200) NOT NULL,
+  JOB_GROUP         VARCHAR(200) NOT NULL,
+  DESCRIPTION       VARCHAR(250) NULL,
+  JOB_CLASS_NAME    VARCHAR(250) NOT NULL,
+  IS_DURABLE        BOOLEAN      NOT NULL,
+  IS_NONCONCURRENT  BOOLEAN      NOT NULL,
+  IS_UPDATE_DATA    BOOLEAN      NOT NULL,
+  REQUESTS_RECOVERY BOOLEAN      NOT NULL,
+  JOB_DATA          IMAGE        NULL
+);
+
+CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
+  SCHED_NAME      VARCHAR(120) NOT NULL,
+  TRIGGER_NAME    VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP   VARCHAR(200) NOT NULL,
+  REPEAT_COUNT    BIGINT       NOT NULL,
+  REPEAT_INTERVAL BIGINT       NOT NULL,
+  TIMES_TRIGGERED BIGINT       NOT NULL
+);
+
+CREATE TABLE qrtz_simprop_triggers
+(
+  SCHED_NAME    VARCHAR(120)   NOT NULL,
+  TRIGGER_NAME  VARCHAR(200)   NOT NULL,
+  TRIGGER_GROUP VARCHAR(200)   NOT NULL,
+  STR_PROP_1    VARCHAR(512)   NULL,
+  STR_PROP_2    VARCHAR(512)   NULL,
+  STR_PROP_3    VARCHAR(512)   NULL,
+  INT_PROP_1    INTEGER        NULL,
+  INT_PROP_2    INTEGER        NULL,
+  LONG_PROP_1   BIGINT         NULL,
+  LONG_PROP_2   BIGINT         NULL,
+  DEC_PROP_1    NUMERIC(13, 4) NULL,
+  DEC_PROP_2    NUMERIC(13, 4) NULL,
+  BOOL_PROP_1   BOOLEAN        NULL,
+  BOOL_PROP_2   BOOLEAN        NULL,
+);
+
+CREATE TABLE QRTZ_BLOB_TRIGGERS (
+  SCHED_NAME    VARCHAR(120) NOT NULL,
+  TRIGGER_NAME  VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP VARCHAR(200) NOT NULL,
+  BLOB_DATA     IMAGE        NULL
+);
+
+CREATE TABLE QRTZ_TRIGGERS (
+  SCHED_NAME     VARCHAR(120) NOT NULL,
+  TRIGGER_NAME   VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP  VARCHAR(200) NOT NULL,
+  JOB_NAME       VARCHAR(200) NOT NULL,
+  JOB_GROUP      VARCHAR(200) NOT NULL,
+  DESCRIPTION    VARCHAR(250) NULL,
+  NEXT_FIRE_TIME BIGINT       NULL,
+  PREV_FIRE_TIME BIGINT       NULL,
+  PRIORITY       INTEGER      NULL,
+  TRIGGER_STATE  VARCHAR(16)  NOT NULL,
+  TRIGGER_TYPE   VARCHAR(8)   NOT NULL,
+  START_TIME     BIGINT       NOT NULL,
+  END_TIME       BIGINT       NULL,
+  CALENDAR_NAME  VARCHAR(200) NULL,
+  MISFIRE_INSTR  SMALLINT     NULL,
+  JOB_DATA       IMAGE        NULL
+);
+
+ALTER TABLE QRTZ_CALENDARS
+  ADD
+  CONSTRAINT PK_QRTZ_CALENDARS PRIMARY KEY
+    (
+      SCHED_NAME,
+      CALENDAR_NAME
+    );
+
+ALTER TABLE QRTZ_CRON_TRIGGERS
+  ADD
+  CONSTRAINT PK_QRTZ_CRON_TRIGGERS PRIMARY KEY
+    (
+      SCHED_NAME,
+      TRIGGER_NAME,
+      TRIGGER_GROUP
+    );
+
+ALTER TABLE QRTZ_FIRED_TRIGGERS
+  ADD
+  CONSTRAINT PK_QRTZ_FIRED_TRIGGERS PRIMARY KEY
+    (
+      SCHED_NAME,
+      ENTRY_ID
+    );
+
+ALTER TABLE QRTZ_PAUSED_TRIGGER_GRPS
+  ADD
+  CONSTRAINT PK_QRTZ_PAUSED_TRIGGER_GRPS PRIMARY KEY
+    (
+      SCHED_NAME,
+      TRIGGER_GROUP
+    );
+
+ALTER TABLE QRTZ_SCHEDULER_STATE
+  ADD
+  CONSTRAINT PK_QRTZ_SCHEDULER_STATE PRIMARY KEY
+    (
+      SCHED_NAME,
+      INSTANCE_NAME
+    );
+
+ALTER TABLE QRTZ_LOCKS
+  ADD
+  CONSTRAINT PK_QRTZ_LOCKS PRIMARY KEY
+    (
+      SCHED_NAME,
+      LOCK_NAME
+    );
+
+ALTER TABLE QRTZ_JOB_DETAILS
+  ADD
+  CONSTRAINT PK_QRTZ_JOB_DETAILS PRIMARY KEY
+    (
+      SCHED_NAME,
+      JOB_NAME,
+      JOB_GROUP
+    );
+
+ALTER TABLE QRTZ_SIMPLE_TRIGGERS
+  ADD
+  CONSTRAINT PK_QRTZ_SIMPLE_TRIGGERS PRIMARY KEY
+    (
+      SCHED_NAME,
+      TRIGGER_NAME,
+      TRIGGER_GROUP
+    );
+
+ALTER TABLE QRTZ_SIMPROP_TRIGGERS
+  ADD
+  CONSTRAINT PK_QRTZ_SIMPROP_TRIGGERS PRIMARY KEY
+    (
+      SCHED_NAME,
+      TRIGGER_NAME,
+      TRIGGER_GROUP
+    );
+
+ALTER TABLE QRTZ_TRIGGERS
+  ADD
+  CONSTRAINT PK_QRTZ_TRIGGERS PRIMARY KEY
+    (
+      SCHED_NAME,
+      TRIGGER_NAME,
+      TRIGGER_GROUP
+    );
+
+ALTER TABLE QRTZ_CRON_TRIGGERS
+  ADD
+  CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
+    (
+      SCHED_NAME,
+      TRIGGER_NAME,
+      TRIGGER_GROUP
+    ) REFERENCES QRTZ_TRIGGERS (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  ) ON DELETE CASCADE;
+
+
+ALTER TABLE QRTZ_SIMPLE_TRIGGERS
+  ADD
+  CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
+    (
+      SCHED_NAME,
+      TRIGGER_NAME,
+      TRIGGER_GROUP
+    ) REFERENCES QRTZ_TRIGGERS (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  ) ON DELETE CASCADE;
+
+ALTER TABLE QRTZ_SIMPROP_TRIGGERS
+  ADD
+  CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
+    (
+      SCHED_NAME,
+      TRIGGER_NAME,
+      TRIGGER_GROUP
+    ) REFERENCES QRTZ_TRIGGERS (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  ) ON DELETE CASCADE;
+
+
+ALTER TABLE QRTZ_TRIGGERS
+  ADD
+  CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS FOREIGN KEY
+    (
+      SCHED_NAME,
+      JOB_NAME,
+      JOB_GROUP
+    ) REFERENCES QRTZ_JOB_DETAILS (
+    SCHED_NAME,
+    JOB_NAME,
+    JOB_GROUP
+  );

+ 177 - 1
hsweb-web-bean/src/main/resources/system/install/sql/mysql/install.sql

@@ -278,4 +278,180 @@ CREATE TABLE s_data_source
   test_sql    VARCHAR(512) COMMENT '测试sql'
 );
 ALTER TABLE s_data_source
-  COMMENT '数据源';
+  COMMENT '数据源';
+
+
+CREATE TABLE S_QUARTZ_JOB_HIS (
+  u_id       VARCHAR(32) NOT NULL  PRIMARY KEY
+  COMMENT '主键',
+  job_id     VARCHAR(32) NOT NULL
+  COMMENT '任务ID',
+  start_time DATETIME    NOT NULL
+  COMMENT '开始时间',
+  end_time   DATETIME COMMENT '结束时间',
+  result     TEXT COMMENT '执行结果',
+  status     TINYINT COMMENT '状态'
+);
+
+CREATE TABLE S_QUARTZ_JOB (
+  u_id       VARCHAR(32)  NOT NULL PRIMARY KEY
+  COMMENT '主键',
+  name       VARCHAR(128) NOT NULL
+  COMMENT '主键',
+  remark     VARCHAR(512) COMMENT '主键',
+  cron       VARCHAR(512) NOT NULL
+  COMMENT '主键',
+  script     TEXT         NOT NULL
+  COMMENT '主键',
+  language   VARCHAR(32)  NOT NULL
+  COMMENT '主键',
+  enabled    TINYINT COMMENT '主键',
+  parameters TEXT COMMENT '主键',
+  type       TINYINT
+);
+
+
+CREATE TABLE QRTZ_JOB_DETAILS
+(
+  SCHED_NAME        VARCHAR(120) NOT NULL,
+  JOB_NAME          VARCHAR(200) NOT NULL,
+  JOB_GROUP         VARCHAR(200) NOT NULL,
+  DESCRIPTION       VARCHAR(250) NULL,
+  JOB_CLASS_NAME    VARCHAR(250) NOT NULL,
+  IS_DURABLE        VARCHAR(1)   NOT NULL,
+  IS_NONCONCURRENT  VARCHAR(1)   NOT NULL,
+  IS_UPDATE_DATA    VARCHAR(1)   NOT NULL,
+  REQUESTS_RECOVERY VARCHAR(1)   NOT NULL,
+  JOB_DATA          BLOB         NULL,
+  PRIMARY KEY (SCHED_NAME, JOB_NAME, JOB_GROUP)
+);
+
+CREATE TABLE QRTZ_TRIGGERS
+(
+  SCHED_NAME     VARCHAR(120) NOT NULL,
+  TRIGGER_NAME   VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP  VARCHAR(200) NOT NULL,
+  JOB_NAME       VARCHAR(200) NOT NULL,
+  JOB_GROUP      VARCHAR(200) NOT NULL,
+  DESCRIPTION    VARCHAR(250) NULL,
+  NEXT_FIRE_TIME BIGINT(13)   NULL,
+  PREV_FIRE_TIME BIGINT(13)   NULL,
+  PRIORITY       INTEGER      NULL,
+  TRIGGER_STATE  VARCHAR(16)  NOT NULL,
+  TRIGGER_TYPE   VARCHAR(8)   NOT NULL,
+  START_TIME     BIGINT(13)   NOT NULL,
+  END_TIME       BIGINT(13)   NULL,
+  CALENDAR_NAME  VARCHAR(200) NULL,
+  MISFIRE_INSTR  SMALLINT(2)  NULL,
+  JOB_DATA       BLOB         NULL,
+  PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
+  FOREIGN KEY (SCHED_NAME, JOB_NAME, JOB_GROUP)
+  REFERENCES QRTZ_JOB_DETAILS (SCHED_NAME, JOB_NAME, JOB_GROUP)
+);
+
+CREATE TABLE QRTZ_SIMPLE_TRIGGERS
+(
+  SCHED_NAME      VARCHAR(120) NOT NULL,
+  TRIGGER_NAME    VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP   VARCHAR(200) NOT NULL,
+  REPEAT_COUNT    BIGINT(7)    NOT NULL,
+  REPEAT_INTERVAL BIGINT(12)   NOT NULL,
+  TIMES_TRIGGERED BIGINT(10)   NOT NULL,
+  PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
+  FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
+  REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
+);
+
+CREATE TABLE QRTZ_CRON_TRIGGERS
+(
+  SCHED_NAME      VARCHAR(120) NOT NULL,
+  TRIGGER_NAME    VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP   VARCHAR(200) NOT NULL,
+  CRON_EXPRESSION VARCHAR(200) NOT NULL,
+  TIME_ZONE_ID    VARCHAR(80),
+  PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
+  FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
+  REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
+);
+
+CREATE TABLE QRTZ_SIMPROP_TRIGGERS
+(
+  SCHED_NAME    VARCHAR(120)   NOT NULL,
+  TRIGGER_NAME  VARCHAR(200)   NOT NULL,
+  TRIGGER_GROUP VARCHAR(200)   NOT NULL,
+  STR_PROP_1    VARCHAR(512)   NULL,
+  STR_PROP_2    VARCHAR(512)   NULL,
+  STR_PROP_3    VARCHAR(512)   NULL,
+  INT_PROP_1    INT            NULL,
+  INT_PROP_2    INT            NULL,
+  LONG_PROP_1   BIGINT         NULL,
+  LONG_PROP_2   BIGINT         NULL,
+  DEC_PROP_1    NUMERIC(13, 4) NULL,
+  DEC_PROP_2    NUMERIC(13, 4) NULL,
+  BOOL_PROP_1   VARCHAR(1)     NULL,
+  BOOL_PROP_2   VARCHAR(1)     NULL,
+  PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
+  FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
+  REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
+);
+
+CREATE TABLE QRTZ_BLOB_TRIGGERS
+(
+  SCHED_NAME    VARCHAR(120) NOT NULL,
+  TRIGGER_NAME  VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP VARCHAR(200) NOT NULL,
+  BLOB_DATA     BLOB         NULL,
+  PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
+  FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
+  REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
+);
+
+CREATE TABLE QRTZ_CALENDARS
+(
+  SCHED_NAME    VARCHAR(120) NOT NULL,
+  CALENDAR_NAME VARCHAR(200) NOT NULL,
+  CALENDAR      BLOB         NOT NULL,
+  PRIMARY KEY (SCHED_NAME, CALENDAR_NAME)
+);
+
+CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
+(
+  SCHED_NAME    VARCHAR(120) NOT NULL,
+  TRIGGER_GROUP VARCHAR(200) NOT NULL,
+  PRIMARY KEY (SCHED_NAME, TRIGGER_GROUP)
+);
+
+CREATE TABLE QRTZ_FIRED_TRIGGERS
+(
+  SCHED_NAME        VARCHAR(120) NOT NULL,
+  ENTRY_ID          VARCHAR(95)  NOT NULL,
+  TRIGGER_NAME      VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP     VARCHAR(200) NOT NULL,
+  INSTANCE_NAME     VARCHAR(200) NOT NULL,
+  FIRED_TIME        BIGINT(13)   NOT NULL,
+  SCHED_TIME        BIGINT(13)   NOT NULL,
+  PRIORITY          INTEGER      NOT NULL,
+  STATE             VARCHAR(16)  NOT NULL,
+  JOB_NAME          VARCHAR(200) NULL,
+  JOB_GROUP         VARCHAR(200) NULL,
+  IS_NONCONCURRENT  VARCHAR(1)   NULL,
+  REQUESTS_RECOVERY VARCHAR(1)   NULL,
+  PRIMARY KEY (SCHED_NAME, ENTRY_ID)
+);
+
+CREATE TABLE QRTZ_SCHEDULER_STATE
+(
+  SCHED_NAME        VARCHAR(120) NOT NULL,
+  INSTANCE_NAME     VARCHAR(200) NOT NULL,
+  LAST_CHECKIN_TIME BIGINT(13)   NOT NULL,
+  CHECKIN_INTERVAL  BIGINT(13)   NOT NULL,
+  PRIMARY KEY (SCHED_NAME, INSTANCE_NAME)
+);
+
+CREATE TABLE QRTZ_LOCKS
+(
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  LOCK_NAME  VARCHAR(40)  NOT NULL,
+  PRIMARY KEY (SCHED_NAME, LOCK_NAME)
+);
+

+ 228 - 12
hsweb-web-bean/src/main/resources/system/install/sql/oracle/install.sql

@@ -265,17 +265,17 @@ COMMENT ON COLUMN ${jdbc.username}."S_QUERY_PLAN"."CREATE_DATE" IS '创建日期
 
 CREATE TABLE ${jdbc.username}.S_DATA_SOURCE
 (
-  U_ID VARCHAR2(32) PRIMARY KEY NOT NULL,
-  NAME VARCHAR2(64) NOT NULL,
-  DRIVER VARCHAR2(128) NOT NULL,
-  URL VARCHAR2(512) NOT NULL,
-  USERNAME VARCHAR2(128) NOT NULL,
-  PASSWORD VARCHAR2(128) NOT NULL,
-  ENABLED NUMBER(4) NOT NULL,
-  CREATE_DATE DATE NOT NULL,
-  PROPERTIES CLOB,
-  COMMENT VARCHAR2(512),
-  TEST_SQL VARCHAR2(512)
+  U_ID        VARCHAR2(32) PRIMARY KEY NOT NULL,
+  NAME        VARCHAR2(64)             NOT NULL,
+  DRIVER      VARCHAR2(128)            NOT NULL,
+  URL         VARCHAR2(512)            NOT NULL,
+  USERNAME    VARCHAR2(128)            NOT NULL,
+  PASSWORD    VARCHAR2(128)            NOT NULL,
+  ENABLED     NUMBER(4)                NOT NULL,
+  CREATE_DATE DATE                     NOT NULL,
+  PROPERTIES  CLOB,
+  COMMENT     VARCHAR2(512),
+  TEST_SQL    VARCHAR2(512)
 );
 COMMENT ON COLUMN ${jdbc.username}.S_DATA_SOURCE.U_ID IS 'ID';
 COMMENT ON COLUMN ${jdbc.username}.S_DATA_SOURCE.NAME IS '数据源名称';
@@ -312,4 +312,220 @@ ALTER TABLE ${jdbc.username}."S_SCRIPT"
 ALTER TABLE ${jdbc.username}."S_USER"
   ADD PRIMARY KEY ("U_ID");
 ALTER TABLE ${jdbc.username}."S_USER_ROLE"
-  ADD PRIMARY KEY ("U_ID");
+  ADD PRIMARY KEY ("U_ID");
+
+--定时任务
+CREATE TABLE ${jdbc.username}.S_QUARTZ_JOB_HIS (
+  u_id       VARCHAR(32) NOT NULL  PRIMARY KEY,
+  job_id     VARCHAR(32) NOT NULL,
+  start_time DATE        NOT NULL,
+  end_time   DATE,
+  result     CLOB,
+  status     NUMBER(4)
+);
+COMMENT ON COLUMN ${jdbc.username}.S_QUARTZ_JOB_HIS.u_id IS '主键';
+COMMENT ON COLUMN ${jdbc.username}.S_QUARTZ_JOB_HIS.job_id IS '任务ID';
+COMMENT ON COLUMN ${jdbc.username}.S_QUARTZ_JOB_HIS.start_time IS '开始时间';
+COMMENT ON COLUMN ${jdbc.username}.S_QUARTZ_JOB_HIS.end_time IS '结束时间';
+COMMENT ON COLUMN ${jdbc.username}.S_QUARTZ_JOB_HIS.result IS '执行结果';
+COMMENT ON COLUMN ${jdbc.username}.S_QUARTZ_JOB_HIS.status IS '状态';
+
+
+CREATE TABLE ${jdbc.username}.S_QUARTZ_JOB (
+  u_id       VARCHAR(32)  NOT NULL PRIMARY KEY,
+  name       VARCHAR(128) NOT NULL,
+  remark     VARCHAR(512),
+  cron       ${jdbc.username}. VARCHAR(512) NOT NULL,
+  script     CLOB         NOT NULL,
+  language   VARCHAR(32)  NOT NULL,
+  enabled    NUMBER(4),
+  parameters CLOB,
+  type       NUMBER(4)
+);
+COMMENT ON COLUMN ${jdbc.username}.S_QUARTZ_JOB.u_id IS '主键';
+COMMENT ON COLUMN ${jdbc.username}.S_QUARTZ_JOB.name IS '任务名称';
+COMMENT ON COLUMN ${jdbc.username}.S_QUARTZ_JOB.remark IS '备注';
+COMMENT ON COLUMN ${jdbc.username}.S_QUARTZ_JOB.cron ${jdbc.username}.IS 'cron表达式';
+COMMENT ON COLUMN ${jdbc.username}.S_QUARTZ_JOB.script IS '执行脚本';
+COMMENT ON COLUMN ${jdbc.username}.S_QUARTZ_JOB.language IS '脚本语言';
+COMMENT ON COLUMN ${jdbc.username}.S_QUARTZ_JOB.enabled IS '是否启用';
+COMMENT ON COLUMN ${jdbc.username}.S_QUARTZ_JOB.parameters IS '启动参数';
+COMMENT ON COLUMN ${jdbc.username}.S_QUARTZ_JOB.type IS '任务类型';
+
+
+CREATE TABLE ${jdbc.username}.qrtz_job_details
+(
+  SCHED_NAME        VARCHAR2(120) NOT NULL,
+  JOB_NAME          VARCHAR2(200) NOT NULL,
+  JOB_GROUP         VARCHAR2(200) NOT NULL,
+  DESCRIPTION       VARCHAR2(250) NULL,
+  JOB_CLASS_NAME    VARCHAR2(250) NOT NULL,
+  IS_DURABLE        VARCHAR2(1)   NOT NULL,
+  IS_NONCONCURRENT  VARCHAR2(1)   NOT NULL,
+  IS_UPDATE_DATA    VARCHAR2(1)   NOT NULL,
+  REQUESTS_RECOVERY VARCHAR2(1)   NOT NULL,
+  JOB_DATA          BLOB          NULL,
+  CONSTRAINT QRTZ_JOB_DETAILS_PK PRIMARY KEY (SCHED_NAME, JOB_NAME, JOB_GROUP)
+);
+CREATE TABLE ${jdbc.username}.qrtz_triggers
+(
+  SCHED_NAME     VARCHAR2(120) NOT NULL,
+  TRIGGER_NAME   VARCHAR2(200) NOT NULL,
+  TRIGGER_GROUP  VARCHAR2(200) NOT NULL,
+  JOB_NAME       VARCHAR2(200) NOT NULL,
+  JOB_GROUP      VARCHAR2(200) NOT NULL,
+  DESCRIPTION    VARCHAR2(250) NULL,
+  NEXT_FIRE_TIME NUMBER(13)    NULL,
+  PREV_FIRE_TIME NUMBER(13)    NULL,
+  PRIORITY       NUMBER(13)    NULL,
+  TRIGGER_STATE  VARCHAR2(16)  NOT NULL,
+  TRIGGER_TYPE   VARCHAR2(8)   NOT NULL,
+  START_TIME     NUMBER(13)    NOT NULL,
+  END_TIME       NUMBER(13)    NULL,
+  CALENDAR_NAME  VARCHAR2(200) NULL,
+  MISFIRE_INSTR  NUMBER(2)     NULL,
+  JOB_DATA       BLOB          NULL,
+  CONSTRAINT QRTZ_TRIGGERS_PK PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
+  CONSTRAINT QRTZ_TRIGGER_TO_JOBS_FK FOREIGN KEY (SCHED_NAME, JOB_NAME, JOB_GROUP)
+  REFERENCES QRTZ_JOB_DETAILS (SCHED_NAME, JOB_NAME, JOB_GROUP)
+);
+CREATE TABLE ${jdbc.username}.qrtz_simple_triggers
+(
+  SCHED_NAME      VARCHAR2(120) NOT NULL,
+  TRIGGER_NAME    VARCHAR2(200) NOT NULL,
+  TRIGGER_GROUP   VARCHAR2(200) NOT NULL,
+  REPEAT_COUNT    NUMBER(7)     NOT NULL,
+  REPEAT_INTERVAL NUMBER(12)    NOT NULL,
+  TIMES_TRIGGERED NUMBER(10)    NOT NULL,
+  CONSTRAINT QRTZ_SIMPLE_TRIG_PK PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
+  CONSTRAINT QRTZ_SIMPLE_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
+  REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
+);
+CREATE TABLE ${jdbc.username}.qrtz_cron_triggers
+(
+  SCHED_NAME      VARCHAR2(120) NOT NULL,
+  TRIGGER_NAME    VARCHAR2(200) NOT NULL,
+  TRIGGER_GROUP   VARCHAR2(200) NOT NULL,
+  CRON_EXPRESSION VARCHAR2(120) NOT NULL,
+  TIME_ZONE_ID    VARCHAR2(80),
+  CONSTRAINT QRTZ_CRON_TRIG_PK PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
+  CONSTRAINT QRTZ_CRON_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
+  REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
+);
+CREATE TABLE ${jdbc.username}.qrtz_simprop_triggers
+(
+  SCHED_NAME    VARCHAR2(120)  NOT NULL,
+  TRIGGER_NAME  VARCHAR2(200)  NOT NULL,
+  TRIGGER_GROUP VARCHAR2(200)  NOT NULL,
+  STR_PROP_1    VARCHAR2(512)  NULL,
+  STR_PROP_2    VARCHAR2(512)  NULL,
+  STR_PROP_3    VARCHAR2(512)  NULL,
+  INT_PROP_1    NUMBER(10)     NULL,
+  INT_PROP_2    NUMBER(10)     NULL,
+  LONG_PROP_1   NUMBER(13)     NULL,
+  LONG_PROP_2   NUMBER(13)     NULL,
+  DEC_PROP_1    NUMERIC(13, 4) NULL,
+  DEC_PROP_2    NUMERIC(13, 4) NULL,
+  BOOL_PROP_1   VARCHAR2(1)    NULL,
+  BOOL_PROP_2   VARCHAR2(1)    NULL,
+  CONSTRAINT QRTZ_SIMPROP_TRIG_PK PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
+  CONSTRAINT QRTZ_SIMPROP_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
+  REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
+);
+CREATE TABLE ${jdbc.username}.qrtz_blob_triggers
+(
+  SCHED_NAME    VARCHAR2(120) NOT NULL,
+  TRIGGER_NAME  VARCHAR2(200) NOT NULL,
+  TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+  BLOB_DATA     BLOB          NULL,
+  CONSTRAINT QRTZ_BLOB_TRIG_PK PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
+  CONSTRAINT QRTZ_BLOB_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
+  REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
+);
+CREATE TABLE ${jdbc.username}.qrtz_calendars
+(
+  SCHED_NAME    VARCHAR2(120) NOT NULL,
+  CALENDAR_NAME VARCHAR2(200) NOT NULL,
+  CALENDAR      BLOB          NOT NULL,
+  CONSTRAINT QRTZ_CALENDARS_PK PRIMARY KEY (SCHED_NAME, CALENDAR_NAME)
+);
+CREATE TABLE ${jdbc.username}.qrtz_paused_trigger_grps
+(
+  SCHED_NAME    VARCHAR2(120) NOT NULL,
+  TRIGGER_GROUP VARCHAR2(200) NOT NULL,
+  CONSTRAINT QRTZ_PAUSED_TRIG_GRPS_PK PRIMARY KEY (SCHED_NAME, TRIGGER_GROUP)
+);
+CREATE TABLE ${jdbc.username}.qrtz_fired_triggers
+(
+  SCHED_NAME        VARCHAR2(120) NOT NULL,
+  ENTRY_ID          VARCHAR2(95)  NOT NULL,
+  TRIGGER_NAME      VARCHAR2(200) NOT NULL,
+  TRIGGER_GROUP     VARCHAR2(200) NOT NULL,
+  INSTANCE_NAME     VARCHAR2(200) NOT NULL,
+  FIRED_TIME        NUMBER(13)    NOT NULL,
+  SCHED_TIME        NUMBER(13)    NOT NULL,
+  PRIORITY          NUMBER(13)    NOT NULL,
+  STATE             VARCHAR2(16)  NOT NULL,
+  JOB_NAME          VARCHAR2(200) NULL,
+  JOB_GROUP         VARCHAR2(200) NULL,
+  IS_NONCONCURRENT  VARCHAR2(1)   NULL,
+  REQUESTS_RECOVERY VARCHAR2(1)   NULL,
+  CONSTRAINT QRTZ_FIRED_TRIGGER_PK PRIMARY KEY (SCHED_NAME, ENTRY_ID)
+);
+CREATE TABLE ${jdbc.username}.qrtz_scheduler_state
+(
+  SCHED_NAME        VARCHAR2(120) NOT NULL,
+  INSTANCE_NAME     VARCHAR2(200) NOT NULL,
+  LAST_CHECKIN_TIME NUMBER(13)    NOT NULL,
+  CHECKIN_INTERVAL  NUMBER(13)    NOT NULL,
+  CONSTRAINT QRTZ_SCHEDULER_STATE_PK PRIMARY KEY (SCHED_NAME, INSTANCE_NAME)
+);
+CREATE TABLE ${jdbc.username}.qrtz_locks
+(
+  SCHED_NAME VARCHAR2(120) NOT NULL,
+  LOCK_NAME  VARCHAR2(40)  NOT NULL,
+  CONSTRAINT QRTZ_LOCKS_PK PRIMARY KEY (SCHED_NAME, LOCK_NAME)
+);
+
+CREATE INDEX idx_qrtz_j_req_recovery
+  ON ${jdbc.username}.${jdbc.username}.qrtz_job_details (SCHED_NAME, REQUESTS_RECOVERY);
+CREATE INDEX idx_qrtz_j_grp
+  ON ${jdbc.username}.${jdbc.username}.qrtz_job_details (SCHED_NAME, JOB_GROUP);
+
+CREATE INDEX idx_qrtz_t_j
+  ON ${jdbc.username}.${jdbc.username}.qrtz_triggers (SCHED_NAME, JOB_NAME, JOB_GROUP);
+CREATE INDEX idx_qrtz_t_jg
+  ON ${jdbc.username}.qrtz_triggers (SCHED_NAME, JOB_GROUP);
+CREATE INDEX idx_qrtz_t_c
+  ON ${jdbc.username}.qrtz_triggers (SCHED_NAME, CALENDAR_NAME);
+CREATE INDEX idx_qrtz_t_g
+  ON ${jdbc.username}.qrtz_triggers (SCHED_NAME, TRIGGER_GROUP);
+CREATE INDEX idx_qrtz_t_state
+  ON ${jdbc.username}.qrtz_triggers (SCHED_NAME, TRIGGER_STATE);
+CREATE INDEX idx_qrtz_t_n_state
+  ON ${jdbc.username}.qrtz_triggers (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP, TRIGGER_STATE);
+CREATE INDEX idx_qrtz_t_n_g_state
+  ON ${jdbc.username}.qrtz_triggers (SCHED_NAME, TRIGGER_GROUP, TRIGGER_STATE);
+CREATE INDEX idx_qrtz_t_next_fire_time
+  ON ${jdbc.username}.qrtz_triggers (SCHED_NAME, NEXT_FIRE_TIME);
+CREATE INDEX idx_qrtz_t_nft_st
+  ON ${jdbc.username}.qrtz_triggers (SCHED_NAME, TRIGGER_STATE, NEXT_FIRE_TIME);
+CREATE INDEX idx_qrtz_t_nft_misfire
+  ON ${jdbc.username}.qrtz_triggers (SCHED_NAME, MISFIRE_INSTR, NEXT_FIRE_TIME);
+CREATE INDEX idx_qrtz_t_nft_st_misfire
+  ON ${jdbc.username}.qrtz_triggers (SCHED_NAME, MISFIRE_INSTR, NEXT_FIRE_TIME, TRIGGER_STATE);
+CREATE INDEX idx_qrtz_t_nft_st_misfire_grp
+  ON ${jdbc.username}.qrtz_triggers (SCHED_NAME, MISFIRE_INSTR, NEXT_FIRE_TIME, TRIGGER_GROUP, TRIGGER_STATE);
+
+CREATE INDEX idx_qrtz_ft_trig_inst_name
+  ON ${jdbc.username}.qrtz_fired_triggers (SCHED_NAME, INSTANCE_NAME);
+CREATE INDEX idx_qrtz_ft_inst_job_req_rcvry
+  ON ${jdbc.username}.qrtz_fired_triggers (SCHED_NAME, INSTANCE_NAME, REQUESTS_RECOVERY);
+CREATE INDEX idx_qrtz_ft_j_g
+  ON ${jdbc.username}.qrtz_fired_triggers (SCHED_NAME, JOB_NAME, JOB_GROUP);
+CREATE INDEX idx_qrtz_ft_jg
+  ON ${jdbc.username}.qrtz_fired_triggers (SCHED_NAME, JOB_GROUP);
+CREATE INDEX idx_qrtz_ft_t_g
+  ON ${jdbc.username}.qrtz_fired_triggers (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP);
+CREATE INDEX idx_qrtz_ft_tg
+  ON ${jdbc.username}.qrtz_fired_triggers (SCHED_NAME, TRIGGER_GROUP);

+ 84 - 0
hsweb-web-controller/src/main/java/org/hsweb/web/controller/quartz/QuartzJobController.java

@@ -0,0 +1,84 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.controller.quartz;
+
+import org.hsweb.web.bean.common.QueryParam;
+import org.hsweb.web.bean.po.quartz.QuartzJob;
+import org.hsweb.web.controller.GenericController;
+import org.hsweb.web.core.logger.annotation.AccessLogger;
+import org.hsweb.web.core.authorize.annotation.Authorize;
+import org.hsweb.web.core.message.ResponseMessage;
+import org.hsweb.web.service.quartz.QuartzJobHistoryService;
+import org.springframework.web.bind.annotation.*;
+import org.hsweb.web.service.quartz.QuartzJobService;
+
+import javax.annotation.Resource;
+
+/**
+ * 定时调度任务控制器
+ * Created by hsweb-generator
+ */
+@RestController
+@RequestMapping(value = "/quartz")
+@AccessLogger("定时调度任务")
+@Authorize(module = "quartz")
+public class QuartzJobController extends GenericController<QuartzJob, String> {
+
+    @Resource
+    private QuartzJobService quartzJobService;
+
+    @Resource
+    private QuartzJobHistoryService quartzJobHistoryService;
+
+    @Override
+    public QuartzJobService getService() {
+        return this.quartzJobService;
+    }
+
+
+    @RequestMapping(value = "/{id}/enable", method = RequestMethod.PUT)
+    @AccessLogger("启用任务")
+    @Authorize(action = "enable")
+    public ResponseMessage enable(@PathVariable("id") String id) {
+        quartzJobService.enable(id);
+        return ResponseMessage.ok();
+    }
+
+    @RequestMapping(value = "/{id}/disable", method = RequestMethod.PUT)
+    @AccessLogger("禁用任务")
+    @Authorize(action = "disable")
+    public ResponseMessage disable(@PathVariable("id") String id) {
+        quartzJobService.disable(id);
+        return ResponseMessage.ok();
+    }
+
+
+    @RequestMapping(value = "/history/{jobId}", method = RequestMethod.GET)
+    @AccessLogger("执行历史")
+    @Authorize(action = "history")
+    public ResponseMessage history(@PathVariable("jobId") String jobId, QueryParam param) {
+        param.where("jobId", jobId);
+        return ResponseMessage.ok(quartzJobHistoryService.selectPager(param)).onlyData();
+    }
+
+    @RequestMapping(value = "/cron/exec-times/{number:\\d+}", method = RequestMethod.GET, params = "cron")
+    @AccessLogger("获取最近几次执行时间")
+    @Authorize
+    public ResponseMessage history(@RequestParam("cron") String cron, @PathVariable("number") int number) {
+        return ResponseMessage.ok(quartzJobService.getExecTimes(cron, number));
+    }
+}

+ 28 - 0
hsweb-web-dao/hsweb-web-dao-api/src/main/java/org/hsweb/web/dao/quartz/QuartzJobHistoryMapper.java

@@ -0,0 +1,28 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.dao.quartz;
+
+import org.hsweb.web.bean.po.quartz.QuartzJobHistory;
+import org.hsweb.web.dao.GenericMapper;
+
+/**
+* 定时调度任务执行记录数据映射接口
+* Created by generator 
+*/
+public interface QuartzJobHistoryMapper extends GenericMapper<QuartzJobHistory,String> {
+
+}

+ 28 - 0
hsweb-web-dao/hsweb-web-dao-api/src/main/java/org/hsweb/web/dao/quartz/QuartzJobMapper.java

@@ -0,0 +1,28 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.dao.quartz;
+
+import org.hsweb.web.bean.po.quartz.QuartzJob;
+import org.hsweb.web.dao.GenericMapper;
+
+/**
+ * 定时调度任务数据映射接口
+ * Created by generator
+ */
+public interface QuartzJobMapper extends GenericMapper<QuartzJob, String> {
+
+}

+ 63 - 0
hsweb-web-dao/hsweb-web-dao-mybatis/src/main/resources/org/hsweb/web/dao/impl/mybatis/mapper/mysql/quartz/QuartzJobHistoryMapper.xml

@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  ~ Copyright 2015-2016 http://hsweb.me
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.hsweb.web.dao.quartz.QuartzJobHistoryMapper">
+    <resultMap id="QuartzJobHistoryResultMap" type="org.hsweb.web.bean.po.quartz.QuartzJobHistory">
+        <id property="id" column="u_id" javaType="string" jdbcType="VARCHAR"/>
+        <result property="jobId" column="job_id" javaType="String" jdbcType="VARCHAR"/>
+        <result property="startTime" column="start_time" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
+        <result property="endTime" column="end_time" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
+        <result property="result" column="result" javaType="String" jdbcType="CLOB"/>
+        <result property="status" column="status" javaType="byte" jdbcType="NUMERIC"/>
+    </resultMap>
+
+    <!--用于动态生成sql所需的配置-->
+    <sql id="config">
+        <bind name="resultMapId" value="'QuartzJobHistoryResultMap'"/>
+        <bind name="tableName" value="'S_QUARTZ_JOB_HIS'"/>
+    </sql>
+    <insert id="insert" parameterType="org.hsweb.web.bean.common.InsertParam">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildInsertSql"/>
+    </insert>
+
+    <delete id="delete" parameterType="org.hsweb.web.bean.common.DeleteParam">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildDeleteSql"/>
+    </delete>
+
+    <update id="update" parameterType="org.hsweb.web.bean.common.UpdateParam">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildUpdateSql"/>
+    </update>
+
+    <select id="selectByPk" parameterType="string" resultMap="QuartzJobHistoryResultMap">
+        select * from S_QUARTZ_JOB_HIS where u_id=#{id}
+    </select>
+
+    <select id="select" parameterType="org.hsweb.web.bean.common.QueryParam" resultMap="QuartzJobHistoryResultMap">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildSelectSql"/>
+    </select>
+
+    <select id="total" parameterType="org.hsweb.web.bean.common.QueryParam" resultType="int">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildTotalSql"/>
+    </select>
+</mapper>

+ 67 - 0
hsweb-web-dao/hsweb-web-dao-mybatis/src/main/resources/org/hsweb/web/dao/impl/mybatis/mapper/mysql/quartz/QuartzJobMapper.xml

@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  ~ Copyright 2015-2016 http://hsweb.me
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.hsweb.web.dao.quartz.QuartzJobMapper">
+    <resultMap id="QuartzJobResultMap" type="org.hsweb.web.bean.po.quartz.QuartzJob">
+        <id property="id" column="u_id" javaType="string" jdbcType="VARCHAR"/>
+        <result property="name" column="name" javaType="String" jdbcType="VARCHAR"/>
+        <result property="remark" column="remark" javaType="String" jdbcType="VARCHAR"/>
+        <result property="cron" column="cron" javaType="String" jdbcType="VARCHAR"/>
+        <result property="script" column="script" javaType="String" jdbcType="CLOB"/>
+        <result property="language" column="language" javaType="String" jdbcType="VARCHAR"/>
+        <result property="enabled" column="enabled" javaType="boolean" jdbcType="NUMERIC"/>
+        <result property="parameters" column="parameters" javaType="String" jdbcType="CLOB"/>
+        <result property="type" column="type" javaType="byte" jdbcType="NUMERIC"/>
+    </resultMap>
+
+    <!--用于动态生成sql所需的配置-->
+    <sql id="config">
+        <bind name="resultMapId" value="'QuartzJobResultMap'"/>
+        <bind name="tableName" value="'S_QUARTZ_JOB'"/>
+    </sql>
+    <insert id="insert" parameterType="org.hsweb.web.bean.common.InsertParam">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildInsertSql"/>
+    </insert>
+
+    <delete id="delete" parameterType="org.hsweb.web.bean.common.DeleteParam">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildDeleteSql"/>
+    </delete>
+
+    <update id="update" parameterType="org.hsweb.web.bean.common.UpdateParam">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildUpdateSql"/>
+    </update>
+
+    <select id="selectByPk" parameterType="string" resultMap="QuartzJobResultMap">
+        select * from S_QUARTZ_JOB where u_id=#{id}
+    </select>
+
+    <select id="select" parameterType="org.hsweb.web.bean.common.QueryParam" resultMap="QuartzJobResultMap">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildSelectSql"/>
+    </select>
+
+    <select id="total" parameterType="org.hsweb.web.bean.common.QueryParam" resultType="int">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildTotalSql"/>
+    </select>
+</mapper>

+ 63 - 0
hsweb-web-dao/hsweb-web-dao-mybatis/src/main/resources/org/hsweb/web/dao/impl/mybatis/mapper/oracle/quartz/QuartzJobHistoryMapper.xml

@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  ~ Copyright 2015-2016 http://hsweb.me
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.hsweb.web.dao.quartz.QuartzJobHistoryMapper">
+    <resultMap id="QuartzJobHistoryResultMap" type="org.hsweb.web.bean.po.quartz.QuartzJobHistory">
+        <id property="id" column="u_id" javaType="string" jdbcType="VARCHAR"/>
+        <result property="jobId" column="job_id" javaType="String" jdbcType="VARCHAR"/>
+        <result property="startTime" column="start_time" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
+        <result property="endTime" column="end_time" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
+        <result property="result" column="result" javaType="String" jdbcType="CLOB"/>
+        <result property="status" column="status" javaType="byte" jdbcType="NUMERIC"/>
+    </resultMap>
+
+    <!--用于动态生成sql所需的配置-->
+    <sql id="config">
+        <bind name="resultMapId" value="'QuartzJobHistoryResultMap'"/>
+        <bind name="tableName" value="'S_QUARTZ_JOB_HIS'"/>
+    </sql>
+    <insert id="insert" parameterType="org.hsweb.web.bean.common.InsertParam">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildInsertSql"/>
+    </insert>
+
+    <delete id="delete" parameterType="org.hsweb.web.bean.common.DeleteParam">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildDeleteSql"/>
+    </delete>
+
+    <update id="update" parameterType="org.hsweb.web.bean.common.UpdateParam">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildUpdateSql"/>
+    </update>
+
+    <select id="selectByPk" parameterType="string" resultMap="QuartzJobHistoryResultMap">
+        select * from S_QUARTZ_JOB_HIS where u_id=#{id}
+    </select>
+
+    <select id="select" parameterType="org.hsweb.web.bean.common.QueryParam" resultMap="QuartzJobHistoryResultMap">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildSelectSql"/>
+    </select>
+
+    <select id="total" parameterType="org.hsweb.web.bean.common.QueryParam" resultType="int">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildTotalSql"/>
+    </select>
+</mapper>

+ 67 - 0
hsweb-web-dao/hsweb-web-dao-mybatis/src/main/resources/org/hsweb/web/dao/impl/mybatis/mapper/oracle/quartz/QuartzJobMapper.xml

@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  ~ Copyright 2015-2016 http://hsweb.me
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.hsweb.web.dao.quartz.QuartzJobMapper">
+    <resultMap id="QuartzJobResultMap" type="org.hsweb.web.bean.po.quartz.QuartzJob">
+        <id property="id" column="u_id" javaType="string" jdbcType="VARCHAR"/>
+        <result property="name" column="name" javaType="String" jdbcType="VARCHAR"/>
+        <result property="remark" column="remark" javaType="String" jdbcType="VARCHAR"/>
+        <result property="cron" column="cron" javaType="String" jdbcType="VARCHAR"/>
+        <result property="script" column="script" javaType="String" jdbcType="CLOB"/>
+        <result property="language" column="language" javaType="String" jdbcType="VARCHAR"/>
+        <result property="enabled" column="enabled" javaType="boolean" jdbcType="NUMERIC"/>
+        <result property="parameters" column="parameters" javaType="String" jdbcType="CLOB"/>
+        <result property="type" column="type" javaType="byte" jdbcType="NUMERIC"/>
+    </resultMap>
+
+    <!--用于动态生成sql所需的配置-->
+    <sql id="config">
+        <bind name="resultMapId" value="'QuartzJobResultMap'"/>
+        <bind name="tableName" value="'S_QUARTZ_JOB'"/>
+    </sql>
+    <insert id="insert" parameterType="org.hsweb.web.bean.common.InsertParam">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildInsertSql"/>
+    </insert>
+
+    <delete id="delete" parameterType="org.hsweb.web.bean.common.DeleteParam">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildDeleteSql"/>
+    </delete>
+
+    <update id="update" parameterType="org.hsweb.web.bean.common.UpdateParam">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildUpdateSql"/>
+    </update>
+
+    <select id="selectByPk" parameterType="string" resultMap="QuartzJobResultMap">
+        select * from S_QUARTZ_JOB where u_id=#{id}
+    </select>
+
+    <select id="select" parameterType="org.hsweb.web.bean.common.QueryParam" resultMap="QuartzJobResultMap">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildSelectSql"/>
+    </select>
+
+    <select id="total" parameterType="org.hsweb.web.bean.common.QueryParam" resultType="int">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildTotalSql"/>
+    </select>
+</mapper>

+ 1 - 1
hsweb-web-datasource/src/main/java/org/hsweb/web/datasource/dynamic/DynamicDataSourceServiceImpl.java

@@ -175,7 +175,7 @@ public class DynamicDataSourceServiceImpl implements DynamicDataSourceService {
 
     @PostConstruct
     public void init() {
-        if (null != dynamicDataSource)
+        if (null != dynamicDataSource && dynamicDataSource instanceof DynamicXaDataSourceImpl)
             ((DynamicXaDataSourceImpl) dynamicDataSource).setDynamicDataSourceService(this);
     }
 

+ 41 - 0
hsweb-web-service/hsweb-web-service-api/src/main/java/org/hsweb/web/service/quartz/QuartzJobHistoryService.java

@@ -0,0 +1,41 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.service.quartz;
+
+
+import org.hsweb.web.bean.common.PagerResult;
+import org.hsweb.web.bean.common.QueryParam;
+import org.hsweb.web.bean.po.quartz.QuartzJobHistory;
+
+import java.util.List;
+
+/**
+ * 定时调度任务执行记录服务类
+ * Created by generator
+ */
+public interface QuartzJobHistoryService {
+
+    PagerResult<QuartzJobHistory> selectPager(QueryParam param);
+
+    List<QuartzJobHistory> select(QueryParam param);
+
+    int total(QueryParam param);
+
+    String createAndInsertHistory(String jobId);
+
+    boolean endHistory(String historyId, String result, QuartzJobHistory.Status status);
+}

+ 36 - 0
hsweb-web-service/hsweb-web-service-api/src/main/java/org/hsweb/web/service/quartz/QuartzJobService.java

@@ -0,0 +1,36 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.service.quartz;
+
+import org.hsweb.web.bean.po.quartz.QuartzJob;
+import org.hsweb.web.service.GenericService;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 定时调度任务服务类
+ * Created by generator
+ */
+public interface QuartzJobService extends GenericService<QuartzJob, String> {
+
+    void enable(String id);
+
+    void disable(String id);
+
+    List<Date> getExecTimes(String cron, int number);
+}

+ 14 - 0
hsweb-web-service/hsweb-web-service-simple/pom.xml

@@ -18,6 +18,18 @@
             <artifactId>hsweb-web-datasource</artifactId>
             <scope>test</scope>
         </dependency>
+
+        <dependency>
+            <groupId>org.quartz-scheduler</groupId>
+            <artifactId>quartz</artifactId>
+            <version>2.2.3</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context-support</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-redis</artifactId>
@@ -42,11 +54,13 @@
             <artifactId>spring-boot-starter-web</artifactId>
             <scope>test</scope>
         </dependency>
+
         <dependency>
             <groupId>com.oracle</groupId>
             <artifactId>ojdbc14</artifactId>
             <scope>test</scope>
         </dependency>
+
         <dependency>
             <groupId>com.h2database</groupId>
             <artifactId>h2</artifactId>

+ 67 - 0
hsweb-web-service/hsweb-web-service-simple/src/main/java/org/hsweb/web/service/impl/SchedulerAutoConfiguration.java

@@ -0,0 +1,67 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.service.impl;
+
+import org.hsweb.web.service.impl.quartz.SimpleJobFactory;
+import org.quartz.core.QuartzScheduler;
+import org.quartz.impl.StdSchedulerFactory;
+import org.quartz.spi.JobFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.quartz.AdaptableJobFactory;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
+import org.springframework.transaction.PlatformTransactionManager;
+
+import javax.sql.DataSource;
+
+@Configuration
+@ConditionalOnClass(QuartzScheduler.class)
+public class SchedulerAutoConfiguration {
+
+    @Autowired
+    private ApplicationContext applicationContext;
+
+    @Autowired
+    private DataSource dataSource;
+
+    @Autowired
+    private PlatformTransactionManager platformTransactionManager;
+
+    @Bean
+    public JobFactory jobFactory() {
+        SimpleJobFactory jobFactory = new SimpleJobFactory();
+        jobFactory.setDefaultFactory(new AdaptableJobFactory());
+        return jobFactory;
+    }
+
+    @Bean
+    public SchedulerFactoryBean schedulerFactory(JobFactory jobFactory) {
+        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
+        schedulerFactoryBean.setApplicationContext(applicationContext);
+        schedulerFactoryBean.setAutoStartup(true);
+        schedulerFactoryBean.setDataSource(dataSource);
+        schedulerFactoryBean.setTransactionManager(platformTransactionManager);
+        schedulerFactoryBean.setOverwriteExistingJobs(true);
+        schedulerFactoryBean.setSchedulerFactoryClass(StdSchedulerFactory.class);
+        schedulerFactoryBean.setBeanName("scheduler");
+        schedulerFactoryBean.setJobFactory(jobFactory);
+        return schedulerFactoryBean;
+    }
+}

+ 83 - 0
hsweb-web-service/hsweb-web-service-simple/src/main/java/org/hsweb/web/service/impl/quartz/QuartzJobHistoryServiceImpl.java

@@ -0,0 +1,83 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.service.impl.quartz;
+
+import org.hsweb.web.bean.common.*;
+import org.hsweb.web.bean.po.GenericPo;
+import org.hsweb.web.bean.po.quartz.QuartzJobHistory;
+import org.hsweb.web.dao.quartz.QuartzJobHistoryMapper;
+import org.hsweb.web.service.quartz.QuartzJobHistoryService;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 定时调度任务执行记录服务类
+ * Created by generator
+ */
+@Service("quartzJobHistoryService")
+public class QuartzJobHistoryServiceImpl implements QuartzJobHistoryService {
+
+    @Resource
+    protected QuartzJobHistoryMapper quartzJobHistoryMapper;
+
+    @Override
+    public PagerResult<QuartzJobHistory> selectPager(QueryParam param) {
+        PagerResult<QuartzJobHistory> result = new PagerResult<>();
+        int total = total(param);
+        result.setTotal(total);
+        param.rePaging(total);
+        result.setData(select(param));
+        return result;
+    }
+
+    @Override
+    public List<QuartzJobHistory> select(QueryParam param) {
+        return quartzJobHistoryMapper.select(param);
+    }
+
+    @Override
+    public int total(QueryParam param) {
+        return quartzJobHistoryMapper.total(param);
+    }
+
+    @Override
+    @Transactional(propagation = Propagation.NOT_SUPPORTED)
+    public String createAndInsertHistory(String jobId) {
+        QuartzJobHistory history = new QuartzJobHistory();
+        history.setId(QuartzJobHistory.createUID());
+        history.setStatus(QuartzJobHistory.Status.RUNNING.getValue());
+        history.setStartTime(new Date());
+        history.setJobId(jobId);
+        quartzJobHistoryMapper.insert(InsertParam.build(history));
+        return history.getId();
+    }
+
+    @Override
+    @Transactional(propagation = Propagation.NOT_SUPPORTED)
+    public boolean endHistory(String historyId, String result, QuartzJobHistory.Status status) {
+        return quartzJobHistoryMapper.update((UpdateParam) UpdateMapParam.build()
+                .set("result", result)
+                .set("status", status.getValue())
+                .set("endTime", new Date())
+                .where("id", historyId)) == 1;
+    }
+}

+ 223 - 0
hsweb-web-service/hsweb-web-service-simple/src/main/java/org/hsweb/web/service/impl/quartz/QuartzJobServiceImpl.java

@@ -0,0 +1,223 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.service.impl.quartz;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import org.hsweb.commons.StringUtils;
+import org.hsweb.web.bean.common.DeleteParam;
+import org.hsweb.web.bean.common.UpdateMapParam;
+import org.hsweb.web.bean.common.UpdateParam;
+import org.hsweb.web.bean.po.quartz.QuartzJob;
+import org.hsweb.web.core.exception.BusinessException;
+import org.hsweb.web.dao.quartz.QuartzJobHistoryMapper;
+import org.hsweb.web.dao.quartz.QuartzJobMapper;
+import org.hsweb.web.service.impl.AbstractServiceImpl;
+import org.hsweb.web.service.quartz.QuartzJobHistoryService;
+import org.hsweb.web.service.quartz.QuartzJobService;
+import org.joda.time.DateTime;
+import org.quartz.*;
+import org.quartz.Calendar;
+import org.quartz.impl.calendar.CronCalendar;
+import org.quartz.impl.triggers.CronTriggerImpl;
+import org.quartz.spi.MutableTrigger;
+import org.quartz.spi.OperableTrigger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.text.ParseException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 定时调度任务服务类
+ * Created by generator
+ */
+@Service("quartzJobService")
+public class QuartzJobServiceImpl extends AbstractServiceImpl<QuartzJob, String> implements QuartzJobService {
+
+    private static final String CACHE_KEY = "quartz-job";
+
+    @Resource
+    protected QuartzJobMapper quartzJobMapper;
+
+    @Autowired
+    protected Scheduler scheduler;
+
+    @Resource
+    protected QuartzJobHistoryService quartzJobHistoryService;
+
+    @Resource
+    protected QuartzJobHistoryMapper quartzJobHistoryMapper;
+
+    @Override
+    protected QuartzJobMapper getMapper() {
+        return this.quartzJobMapper;
+    }
+
+    @Override
+    @Cacheable(value = CACHE_KEY, key = "'id:'+#id")
+    public QuartzJob selectByPk(String id) {
+        return super.selectByPk(id);
+    }
+
+    @Override
+    public String insert(QuartzJob data) {
+        data.setEnabled(true);
+        String id = super.insert(data);
+        startJob(data);
+        return id;
+    }
+
+    @Override
+    @CacheEvict(value = CACHE_KEY, key = "'id:'+#data.id")
+    public int update(QuartzJob data) {
+        QuartzJob old = selectByPk(data.getId());
+        assertNotNull(old, "任务不存在");
+        int i = getMapper().update(UpdateParam.build(data)
+                .excludes("status", "enabled")
+                .where("id", data.getId()));
+        if (old.isEnabled()) {
+            deleteJob(data.getId());
+            startJob(data);
+        }
+        return i;
+    }
+
+    @Override
+    public int saveOrUpdate(QuartzJob job) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    @CacheEvict(value = CACHE_KEY, key = "'id:'+#id")
+    public void enable(String id) {
+        getMapper().update((UpdateParam) UpdateMapParam.build().set("enabled", true).where("id", id));
+        startJob(getMapper().selectByPk(id));
+    }
+
+    @Override
+    @CacheEvict(value = CACHE_KEY, key = "'id:'+#id")
+    public void disable(String id) {
+        getMapper().update((UpdateParam) UpdateMapParam.build().set("enabled", false).where("id", id));
+        deleteJob(id);
+    }
+
+    @Override
+    @CacheEvict(value = CACHE_KEY, key = "'id:'+#id")
+    public int delete(String id) {
+        deleteJob(id);
+        quartzJobHistoryMapper.delete(DeleteParam.build().where("jobId", id));
+        return super.delete(id);
+    }
+
+    void deleteJob(String id) {
+        JobKey jobKey = createJobKey(id);
+        try {
+            if (scheduler.checkExists(jobKey)) {
+                scheduler.deleteJob(jobKey);
+            }
+        } catch (SchedulerException e) {
+            throw new BusinessException("更新任务失败", e, 500);
+        }
+    }
+
+
+    @Override
+    public List<Date> getExecTimes(String cron, int number) {
+        try {
+            CronTriggerImpl cronTriggerImpl = new CronTriggerImpl();
+            cronTriggerImpl.setCronExpression(cron);
+            return computeFireTimesBetween(cronTriggerImpl, null, new Date(), new DateTime().plusYears(5).toDate(), number);
+        } catch (Exception e) {
+            throw new BusinessException(e.getMessage(), e, 500);
+        }
+    }
+
+    public static List<Date> computeFireTimesBetween(OperableTrigger trigger,
+                                                     org.quartz.Calendar cal, Date from, Date to, int num) {
+        LinkedList<Date> lst = new LinkedList<>();
+        OperableTrigger t = (OperableTrigger) trigger.clone();
+        if (t.getNextFireTime() == null) {
+            t.setStartTime(from);
+            t.setEndTime(to);
+            t.computeFirstFireTime(cal);
+        }
+        for (int i = 0; i < num; i++) {
+            Date d = t.getNextFireTime();
+            if (d != null) {
+                if (d.before(from)) {
+                    t.triggered(cal);
+                    continue;
+                }
+                if (d.after(to)) {
+                    break;
+                }
+                lst.add(d);
+                t.triggered(cal);
+            } else {
+                break;
+            }
+        }
+        return java.util.Collections.unmodifiableList(lst);
+    }
+
+    void startJob(QuartzJob job) {
+        assertNotNull(job, "任务不存在");
+        JobKey key = createJobKey(job.getId());
+        JobDetail jobDetail = JobBuilder.newJob(SimpleJob.class)
+                .withIdentity(key)
+                .setJobData(createJobDataMap(job.getParameters()))
+                .usingJobData(SimpleJobFactory.QUARTZ_ID_KEY, job.getId())
+                .withDescription(job.getName() + (job.getRemark() == null ? "" : job.getRemark()))
+                .build();
+        MutableTrigger trigger = CronScheduleBuilder.cronSchedule(job.getCron()).build();
+        trigger.setKey(createTriggerKey(job.getId()));
+        try {
+            scheduler.scheduleJob(jobDetail, trigger);
+        } catch (SchedulerException e) {
+            throw new BusinessException("创建定时任务失败!", e, 500);
+        }
+    }
+
+    JobDataMap createJobDataMap(String parameters) {
+        JobDataMap map = new JobDataMap();
+        if (!StringUtils.isNullOrEmpty(parameters)) {
+            JSONArray jsonArray = JSON.parseArray(parameters);
+            for (int i = 0; i < jsonArray.size(); i++) {
+                JSONObject o = jsonArray.getJSONObject(i);
+                map.put(o.getString("key"), o.get("value"));
+            }
+        }
+        return map;
+    }
+
+    JobKey createJobKey(String jobId) {
+        return new JobKey(jobId, "hsweb.scheduler");
+    }
+
+    TriggerKey createTriggerKey(String jobId) {
+        return new TriggerKey(jobId, "hsweb.scheduler");
+    }
+
+
+}

+ 118 - 0
hsweb-web-service/hsweb-web-service-simple/src/main/java/org/hsweb/web/service/impl/quartz/SimpleJob.java

@@ -0,0 +1,118 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.service.impl.quartz;
+
+import com.alibaba.fastjson.JSON;
+import org.hsweb.commons.MD5;
+import org.hsweb.commons.StringUtils;
+import org.hsweb.expands.script.engine.DynamicScriptEngine;
+import org.hsweb.expands.script.engine.DynamicScriptEngineFactory;
+import org.hsweb.expands.script.engine.ExecuteResult;
+import org.hsweb.expands.script.engine.ScriptContext;
+import org.hsweb.web.bean.po.quartz.QuartzJob;
+import org.hsweb.web.bean.po.quartz.QuartzJobHistory;
+import org.hsweb.web.service.quartz.QuartzJobHistoryService;
+import org.hsweb.web.service.quartz.QuartzJobService;
+import org.quartz.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.Assert;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@DisallowConcurrentExecution
+public class SimpleJob implements Job {
+    protected Logger logger = LoggerFactory.getLogger(this.getClass());
+    protected QuartzJobService        quartzJobService;
+    protected QuartzJobHistoryService quartzJobHistoryService;
+    protected Map<String, Object>     defaultVar;
+
+    /**
+     * 子类必须实现此构造方法,否则无法创建任务
+     *
+     * @param quartzJobService 定时任务服务类
+     * @param historyService   定时任务历史记录服务类
+     */
+    public SimpleJob(QuartzJobService quartzJobService, QuartzJobHistoryService historyService) {
+        this.quartzJobService = quartzJobService;
+        this.quartzJobHistoryService = historyService;
+    }
+
+    @Override
+    public void execute(JobExecutionContext context) throws JobExecutionException {
+        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
+        String id = jobDataMap.getString(SimpleJobFactory.QUARTZ_ID_KEY);
+        Assert.notNull(id, "定时任务ID错误");
+        QuartzJob job = quartzJobService.selectByPk(id);
+        Assert.notNull(job, "任务不存在");
+        if (logger.isDebugEnabled())
+            logger.debug("start job [{}],data : {}", job.getName(), jobDataMap);
+        DynamicScriptEngine engine = DynamicScriptEngineFactory.getEngine(job.getLanguage());
+        String scriptId = "quartz.job.".concat(id);
+        try {
+            if (!engine.compiled(scriptId)) {
+                engine.compile(scriptId, job.getScript());
+            } else {
+                ScriptContext scriptContext = engine.getContext(scriptId);
+                //脚本发生了变化,自动重新编译
+                if (!MD5.defaultEncode(job.getScript()).equals(scriptContext.getMd5())) {
+                    if (logger.isDebugEnabled())
+                        logger.debug("script is changed,recompile....");
+                    engine.compile(scriptId, job.getScript());
+                }
+            }
+        } catch (Exception e) {
+            throw new JobExecutionException("编译任务脚本失败", e);
+        }
+        if (logger.isDebugEnabled())
+            logger.debug("job running...");
+
+        String hisId = quartzJobHistoryService.createAndInsertHistory(id);
+        Map<String, Object> var = getVar();
+        var.put("context", context);
+        ExecuteResult result = engine.execute(scriptId, var);
+        String strRes;
+        if (logger.isDebugEnabled())
+            logger.debug("job end...{} ", result.isSuccess() ? "success" : "fail");
+        if (result.isSuccess()) {
+            Object res = result.getResult();
+            if (res instanceof String)
+                strRes = ((String) res);
+            else strRes = JSON.toJSONString(res);
+            quartzJobHistoryService.endHistory(hisId, strRes, QuartzJobHistory.Status.SUCCESS);
+        } else {
+            if (result.getException() != null) {
+                strRes = StringUtils.throwable2String(result.getException());
+                logger.error("job failed", result.getException());
+            } else {
+                strRes = result.getMessage();
+                logger.error("job failed {}", strRes);
+            }
+            quartzJobHistoryService.endHistory(hisId, strRes, QuartzJobHistory.Status.FAIL);
+        }
+    }
+
+    public void setDefaultVar(Map<String, Object> defaultVar) {
+        this.defaultVar = defaultVar;
+    }
+
+    public Map<String, Object> getVar() {
+        if (defaultVar == null) return new HashMap<>();
+        return new HashMap<>(defaultVar);
+    }
+}

+ 75 - 0
hsweb-web-service/hsweb-web-service-simple/src/main/java/org/hsweb/web/service/impl/quartz/SimpleJobFactory.java

@@ -0,0 +1,75 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.service.impl.quartz;
+
+import org.hsweb.commons.ClassUtils;
+import org.hsweb.web.core.authorize.ExpressionScopeBean;
+import org.hsweb.web.service.quartz.QuartzJobHistoryService;
+import org.hsweb.web.service.quartz.QuartzJobService;
+import org.quartz.Job;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.quartz.spi.JobFactory;
+import org.quartz.spi.TriggerFiredBundle;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.Assert;
+
+import javax.annotation.Resource;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class SimpleJobFactory implements JobFactory {
+
+    public static final String QUARTZ_ID_KEY = "quartz.id";
+
+    @Resource
+    private QuartzJobService quartzJobService;
+
+    @Resource
+    private QuartzJobHistoryService quartzJobHistoryService;
+
+    private JobFactory defaultFactory;
+
+    @Autowired(required = false)
+    private Map<String, ExpressionScopeBean> expressionScopeBeanMap;
+
+    @Override
+    public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException {
+        Map<String, Object> data = bundle.getJobDetail().getJobDataMap();
+        Class<? extends Job> jobClass = bundle.getJobDetail().getJobClass();
+        if (ClassUtils.instanceOf(jobClass, SimpleJob.class)) {
+            String id = (String) data.get(QUARTZ_ID_KEY);
+            Assert.notNull(id);
+            try {
+                SimpleJob job = (SimpleJob) jobClass.getConstructor(QuartzJobService.class, QuartzJobHistoryService.class).newInstance(quartzJobService, quartzJobHistoryService);
+                if (expressionScopeBeanMap != null)
+                    job.setDefaultVar(new HashMap<>(expressionScopeBeanMap));
+                return job;
+            } catch (Exception e) {
+                throw new SchedulerException("create simple job instance error", e);
+            }
+        } else {
+            if (defaultFactory != null) return defaultFactory.newJob(bundle, scheduler);
+        }
+        throw new SchedulerException("job class not a SimpleJob and defaultFactory is not set!");
+    }
+
+    public void setDefaultFactory(JobFactory defaultFactory) {
+        this.defaultFactory = defaultFactory;
+    }
+}

+ 0 - 1
hsweb-web-service/hsweb-web-service-simple/src/test/java/org/hsweb/web/service/impl/AbstractTestCase.java

@@ -11,5 +11,4 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 @SpringApplicationConfiguration(classes = SpringApplication.class)
 public abstract class AbstractTestCase {
 
-
 }

+ 59 - 0
hsweb-web-service/hsweb-web-service-simple/src/test/java/org/hsweb/web/service/impl/quartz/QuartzJobServiceImplTest.java

@@ -0,0 +1,59 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.service.impl.quartz;
+
+import org.hsweb.web.bean.po.quartz.QuartzJob;
+import org.hsweb.web.service.impl.AbstractTestCase;
+import org.hsweb.web.service.quartz.QuartzJobService;
+import org.junit.Test;
+
+import javax.annotation.Resource;
+
+/**
+ * @author zhouhao
+ */
+public class QuartzJobServiceImplTest extends AbstractTestCase {
+
+    @Resource
+    private QuartzJobService quartzJobService;
+
+    static final String jobId = "test";
+
+    @Test
+    public void testJob() throws InterruptedException {
+        quartzJobService.delete(jobId);
+        QuartzJob job = new QuartzJob();
+        job.setId(jobId);
+        job.setName("测试任务");
+        job.setCron("0/2 * * * * ?");
+        job.setLanguage("groovy");
+        job.setScript("println('任务执行中...');return 'aaaaa';");
+        quartzJobService.insert(job);
+        Thread.sleep(20 * 1000);
+        job.setCron("0/5 * * * * ?");
+        job.setScript("println('任务执行中22222...');return 'aaaaa';");
+        quartzJobService.update(job);
+        Thread.sleep(10 * 1000);
+        quartzJobService.disable(job.getId());
+        Thread.sleep(10 * 1000);
+        quartzJobService.enable(job.getId());
+        Thread.sleep(30 * 1000);
+        quartzJobService.delete(jobId);
+        Thread.sleep(5 * 1000);
+    }
+
+}

+ 68 - 0
hsweb-web-service/hsweb-web-service-simple/src/test/java/org/hsweb/web/service/impl/quartz/QuartzTests.java

@@ -0,0 +1,68 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.service.impl.quartz;
+
+import org.hsweb.web.service.impl.AbstractTestCase;
+import org.junit.Test;
+import org.quartz.*;
+import org.quartz.impl.StdSchedulerFactory;
+import org.quartz.spi.MutableTrigger;
+import org.springframework.context.ApplicationContext;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
+import org.springframework.transaction.PlatformTransactionManager;
+
+import javax.annotation.Resource;
+import javax.sql.DataSource;
+
+public class QuartzTests extends AbstractTestCase {
+    @Resource
+    private ApplicationContext applicationContext;
+
+    @Resource
+    private DataSource dataSource;
+
+    @Resource
+    private PlatformTransactionManager platformTransactionManager;
+
+    @Test
+    public void testQuartz() throws Exception {
+        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
+        schedulerFactoryBean.setApplicationContext(applicationContext);
+        schedulerFactoryBean.setAutoStartup(true);
+        schedulerFactoryBean.setDataSource(dataSource);
+        schedulerFactoryBean.setTransactionManager(platformTransactionManager);
+        schedulerFactoryBean.setOverwriteExistingJobs(true);
+        schedulerFactoryBean.setSchedulerFactoryClass(StdSchedulerFactory.class);
+        schedulerFactoryBean.afterPropertiesSet();
+        schedulerFactoryBean.setBeanName("schedulerFactory");
+        Scheduler scheduler = schedulerFactoryBean.getObject();
+
+//        MutableTrigger trigger   = CronScheduleBuilder.cronSchedule("0/2 * * * * ?").build();
+//        scheduler.deleteJob(new JobKey("test"));
+//        trigger.setKey(new TriggerKey("test"));
+//        scheduler.scheduleJob(JobBuilder.newJob(TestJob.class).withIdentity("test").build(), trigger);
+//        scheduler.deleteJob(new JobKey("test"));
+//        scheduler.scheduleJob(JobBuilder.newJob(TestJob.class).withIdentity("test").build(), trigger);
+        scheduler.resumeAll();
+        scheduler.start();
+
+//        schedulerFactoryBean.start();
+        Thread.sleep(60 * 1000);
+    }
+
+
+}

+ 33 - 0
hsweb-web-service/hsweb-web-service-simple/src/test/java/org/hsweb/web/service/impl/quartz/TestJob.java

@@ -0,0 +1,33 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.service.impl.quartz;
+
+import org.quartz.*;
+
+@DisallowConcurrentExecution
+public class TestJob implements Job {
+    @Override
+    public void execute(JobExecutionContext context) throws JobExecutionException {
+        System.out.println(context.getJobDetail());
+        try {
+            Thread.sleep(5000);
+            System.out.println(111);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 2 - 1
hsweb-web-service/hsweb-web-service-simple/src/test/resources/application.yml

@@ -46,9 +46,10 @@ spring:
         testOnReturn: false
         poolPreparedStatements: true
         maxOpenPreparedStatements: 20
+#        schema: classpath:h2.sql
 mybatis:
     type-aliases-package: org.hsweb.web.bean.po
     mapper-locations: classpath*:org/hsweb/web/dao/impl/mybatis/mapper/oracle/**/*.xml
     config: classpath:mybatis-config.xml
     typeHandlers-package: org.hsweb.web.mybatis.handler
-    dynamic-datasource: on
+#    dynamic-datasource: on

+ 251 - 0
hsweb-web-service/hsweb-web-service-simple/src/test/resources/h2.sql

@@ -0,0 +1,251 @@
+CREATE TABLE QRTZ_CALENDARS (
+  SCHED_NAME    VARCHAR(120) NOT NULL,
+  CALENDAR_NAME VARCHAR(200) NOT NULL,
+  CALENDAR      IMAGE        NOT NULL
+);
+
+CREATE TABLE QRTZ_CRON_TRIGGERS (
+  SCHED_NAME      VARCHAR(120) NOT NULL,
+  TRIGGER_NAME    VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP   VARCHAR(200) NOT NULL,
+  CRON_EXPRESSION VARCHAR(120) NOT NULL,
+  TIME_ZONE_ID    VARCHAR(80)
+);
+
+CREATE TABLE QRTZ_FIRED_TRIGGERS (
+  SCHED_NAME        VARCHAR(120) NOT NULL,
+  ENTRY_ID          VARCHAR(95)  NOT NULL,
+  TRIGGER_NAME      VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP     VARCHAR(200) NOT NULL,
+  INSTANCE_NAME     VARCHAR(200) NOT NULL,
+  FIRED_TIME        BIGINT       NOT NULL,
+  SCHED_TIME        BIGINT       NOT NULL,
+  PRIORITY          INTEGER      NOT NULL,
+  STATE             VARCHAR(16)  NOT NULL,
+  JOB_NAME          VARCHAR(200) NULL,
+  JOB_GROUP         VARCHAR(200) NULL,
+  IS_NONCONCURRENT  BOOLEAN      NULL,
+  REQUESTS_RECOVERY BOOLEAN      NULL
+);
+
+CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
+  SCHED_NAME    VARCHAR(120) NOT NULL,
+  TRIGGER_GROUP VARCHAR(200) NOT NULL
+);
+
+CREATE TABLE QRTZ_SCHEDULER_STATE (
+  SCHED_NAME        VARCHAR(120) NOT NULL,
+  INSTANCE_NAME     VARCHAR(200) NOT NULL,
+  LAST_CHECKIN_TIME BIGINT       NOT NULL,
+  CHECKIN_INTERVAL  BIGINT       NOT NULL
+);
+
+CREATE TABLE QRTZ_LOCKS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  LOCK_NAME  VARCHAR(40)  NOT NULL
+);
+
+CREATE TABLE QRTZ_JOB_DETAILS (
+  SCHED_NAME        VARCHAR(120) NOT NULL,
+  JOB_NAME          VARCHAR(200) NOT NULL,
+  JOB_GROUP         VARCHAR(200) NOT NULL,
+  DESCRIPTION       VARCHAR(250) NULL,
+  JOB_CLASS_NAME    VARCHAR(250) NOT NULL,
+  IS_DURABLE        BOOLEAN      NOT NULL,
+  IS_NONCONCURRENT  BOOLEAN      NOT NULL,
+  IS_UPDATE_DATA    BOOLEAN      NOT NULL,
+  REQUESTS_RECOVERY BOOLEAN      NOT NULL,
+  JOB_DATA          IMAGE        NULL
+);
+
+CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
+  SCHED_NAME      VARCHAR(120) NOT NULL,
+  TRIGGER_NAME    VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP   VARCHAR(200) NOT NULL,
+  REPEAT_COUNT    BIGINT       NOT NULL,
+  REPEAT_INTERVAL BIGINT       NOT NULL,
+  TIMES_TRIGGERED BIGINT       NOT NULL
+);
+
+CREATE TABLE qrtz_simprop_triggers
+(
+  SCHED_NAME    VARCHAR(120)   NOT NULL,
+  TRIGGER_NAME  VARCHAR(200)   NOT NULL,
+  TRIGGER_GROUP VARCHAR(200)   NOT NULL,
+  STR_PROP_1    VARCHAR(512)   NULL,
+  STR_PROP_2    VARCHAR(512)   NULL,
+  STR_PROP_3    VARCHAR(512)   NULL,
+  INT_PROP_1    INTEGER        NULL,
+  INT_PROP_2    INTEGER        NULL,
+  LONG_PROP_1   BIGINT         NULL,
+  LONG_PROP_2   BIGINT         NULL,
+  DEC_PROP_1    NUMERIC(13, 4) NULL,
+  DEC_PROP_2    NUMERIC(13, 4) NULL,
+  BOOL_PROP_1   BOOLEAN        NULL,
+  BOOL_PROP_2   BOOLEAN        NULL,
+);
+
+CREATE TABLE QRTZ_BLOB_TRIGGERS (
+  SCHED_NAME    VARCHAR(120) NOT NULL,
+  TRIGGER_NAME  VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP VARCHAR(200) NOT NULL,
+  BLOB_DATA     IMAGE        NULL
+);
+
+CREATE TABLE QRTZ_TRIGGERS (
+  SCHED_NAME     VARCHAR(120) NOT NULL,
+  TRIGGER_NAME   VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP  VARCHAR(200) NOT NULL,
+  JOB_NAME       VARCHAR(200) NOT NULL,
+  JOB_GROUP      VARCHAR(200) NOT NULL,
+  DESCRIPTION    VARCHAR(250) NULL,
+  NEXT_FIRE_TIME BIGINT       NULL,
+  PREV_FIRE_TIME BIGINT       NULL,
+  PRIORITY       INTEGER      NULL,
+  TRIGGER_STATE  VARCHAR(16)  NOT NULL,
+  TRIGGER_TYPE   VARCHAR(8)   NOT NULL,
+  START_TIME     BIGINT       NOT NULL,
+  END_TIME       BIGINT       NULL,
+  CALENDAR_NAME  VARCHAR(200) NULL,
+  MISFIRE_INSTR  SMALLINT     NULL,
+  JOB_DATA       IMAGE        NULL
+);
+
+ALTER TABLE QRTZ_CALENDARS
+  ADD
+  CONSTRAINT PK_QRTZ_CALENDARS PRIMARY KEY
+    (
+      SCHED_NAME,
+      CALENDAR_NAME
+    );
+
+ALTER TABLE QRTZ_CRON_TRIGGERS
+  ADD
+  CONSTRAINT PK_QRTZ_CRON_TRIGGERS PRIMARY KEY
+    (
+      SCHED_NAME,
+      TRIGGER_NAME,
+      TRIGGER_GROUP
+    );
+
+ALTER TABLE QRTZ_FIRED_TRIGGERS
+  ADD
+  CONSTRAINT PK_QRTZ_FIRED_TRIGGERS PRIMARY KEY
+    (
+      SCHED_NAME,
+      ENTRY_ID
+    );
+
+ALTER TABLE QRTZ_PAUSED_TRIGGER_GRPS
+  ADD
+  CONSTRAINT PK_QRTZ_PAUSED_TRIGGER_GRPS PRIMARY KEY
+    (
+      SCHED_NAME,
+      TRIGGER_GROUP
+    );
+
+ALTER TABLE QRTZ_SCHEDULER_STATE
+  ADD
+  CONSTRAINT PK_QRTZ_SCHEDULER_STATE PRIMARY KEY
+    (
+      SCHED_NAME,
+      INSTANCE_NAME
+    );
+
+ALTER TABLE QRTZ_LOCKS
+  ADD
+  CONSTRAINT PK_QRTZ_LOCKS PRIMARY KEY
+    (
+      SCHED_NAME,
+      LOCK_NAME
+    );
+
+ALTER TABLE QRTZ_JOB_DETAILS
+  ADD
+  CONSTRAINT PK_QRTZ_JOB_DETAILS PRIMARY KEY
+    (
+      SCHED_NAME,
+      JOB_NAME,
+      JOB_GROUP
+    );
+
+ALTER TABLE QRTZ_SIMPLE_TRIGGERS
+  ADD
+  CONSTRAINT PK_QRTZ_SIMPLE_TRIGGERS PRIMARY KEY
+    (
+      SCHED_NAME,
+      TRIGGER_NAME,
+      TRIGGER_GROUP
+    );
+
+ALTER TABLE QRTZ_SIMPROP_TRIGGERS
+  ADD
+  CONSTRAINT PK_QRTZ_SIMPROP_TRIGGERS PRIMARY KEY
+    (
+      SCHED_NAME,
+      TRIGGER_NAME,
+      TRIGGER_GROUP
+    );
+
+ALTER TABLE QRTZ_TRIGGERS
+  ADD
+  CONSTRAINT PK_QRTZ_TRIGGERS PRIMARY KEY
+    (
+      SCHED_NAME,
+      TRIGGER_NAME,
+      TRIGGER_GROUP
+    );
+
+ALTER TABLE QRTZ_CRON_TRIGGERS
+  ADD
+  CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
+    (
+      SCHED_NAME,
+      TRIGGER_NAME,
+      TRIGGER_GROUP
+    ) REFERENCES QRTZ_TRIGGERS (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  ) ON DELETE CASCADE;
+
+
+ALTER TABLE QRTZ_SIMPLE_TRIGGERS
+  ADD
+  CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
+    (
+      SCHED_NAME,
+      TRIGGER_NAME,
+      TRIGGER_GROUP
+    ) REFERENCES QRTZ_TRIGGERS (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  ) ON DELETE CASCADE;
+
+ALTER TABLE QRTZ_SIMPROP_TRIGGERS
+  ADD
+  CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
+    (
+      SCHED_NAME,
+      TRIGGER_NAME,
+      TRIGGER_GROUP
+    ) REFERENCES QRTZ_TRIGGERS (
+    SCHED_NAME,
+    TRIGGER_NAME,
+    TRIGGER_GROUP
+  ) ON DELETE CASCADE;
+
+
+ALTER TABLE QRTZ_TRIGGERS
+  ADD
+  CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS FOREIGN KEY
+    (
+      SCHED_NAME,
+      JOB_NAME,
+      JOB_GROUP
+    ) REFERENCES QRTZ_JOB_DETAILS (
+    SCHED_NAME,
+    JOB_NAME,
+    JOB_GROUP
+  );