diff --git a/smtweb-framework/bpm/pom.xml b/smtweb-framework/bpm/pom.xml
index 867b1d7..2fd5116 100644
--- a/smtweb-framework/bpm/pom.xml
+++ b/smtweb-framework/bpm/pom.xml
@@ -35,6 +35,10 @@
spring-boot-starter-freemarker
+ org.quartz-scheduler
+ quartz
+
+
net.coobird
thumbnailator
[0.4, 0.5)
diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/BpmStartedListener.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/BpmStartedListener.java
index 3c830c4..f640834 100644
--- a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/BpmStartedListener.java
+++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/BpmStartedListener.java
@@ -26,6 +26,7 @@ public class BpmStartedListener implements IStartListener {
SwConsts.SysParam.RUN_PROJECTS = "bpm";
SysServiceFactory.getInstance().reg(new OneTimeTaskCleanService());
TreeHelper.regTreeHelper(ModelCatalog.ENTITY_NAME, ModelCatalogTreeHelper.class);
+
}
@Override
@@ -36,4 +37,9 @@ public class BpmStartedListener implements IStartListener {
CacheManager.getIntance().init();
OneTimeServiceFactory.getInstance().start();
}
+
+ @Override
+ public void close() {
+ OneTimeServiceFactory.getInstance().stop();
+ }
}
diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/BaseJob.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/BaseJob.java
new file mode 100644
index 0000000..86cbbb2
--- /dev/null
+++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/BaseJob.java
@@ -0,0 +1,57 @@
+package cc.smtweb.system.bpm.web.sys.base.job;
+
+import cc.smtweb.framework.core.common.SwConsts;
+import cc.smtweb.framework.core.db.DbEngine;
+import cc.smtweb.framework.core.db.jdbc.ISimpleWorker;
+import cc.smtweb.framework.core.systask.SingleRequestHelper;
+import cc.smtweb.framework.core.util.DateUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+
+/**
+ * Created by Akmm at 2022-09-14 09:51
+ * 定时任务的基类
+ */
+@Slf4j
+public abstract class BaseJob implements Job {
+ @Override
+ public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+ JobEntity job = (JobEntity) jobExecutionContext.getJobDetail().getJobDataMap().get("job");
+
+ final String id = this.getClass().getName();
+ SingleRequestHelper.singleRequest(SwConsts.REDIS_KEY_BASE_JOB, id, job.getName() + "任务执行中,本次忽略.........", () -> {
+ JobLog jlog = startLog(job);
+ try {
+ String info = work();
+ endLog(jlog, true, info);
+ } catch (Exception e) {
+ endLog(jlog, false, e.getMessage());
+ log.error(job.getName() + ":::执行失败", e);
+ }
+
+ });
+ }
+
+ //任务执行信息,可返回执行结果
+ protected abstract String work();
+
+ //存任务日志-开始
+ private JobLog startLog(JobEntity job) {
+ JobLog jlog = new JobLog();
+ jlog.setId(DbEngine.getInstance().nextId());
+ jlog.setSjId(job.getId());
+ jlog.setBeginTime(DateUtil.nowDateTimeLong());
+ DbEngine.getInstance().doTransSingle(() -> DbEngine.getInstance().findDao(JobLog.class).insertEntity(jlog));
+ return jlog;
+ }
+
+ //存任务日志-结束
+ private void endLog(JobLog jlog, boolean sucess, String info) {
+ jlog.setEndTime(DateUtil.nowDateTimeLong());
+ jlog.setSuccess(sucess);
+ jlog.setInfo(info);
+ DbEngine.getInstance().doTransSingle(() -> DbEngine.getInstance().findDao(JobLog.class).updateEntity(jlog));
+ }
+}
diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobCache.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobCache.java
new file mode 100644
index 0000000..40c4594
--- /dev/null
+++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobCache.java
@@ -0,0 +1,30 @@
+package cc.smtweb.system.bpm.web.sys.base.job;
+
+import cc.smtweb.framework.core.annotation.SwCache;
+import cc.smtweb.framework.core.cache.AbstractEntityCache;
+import cc.smtweb.framework.core.cache.CacheManager;
+
+/**
+ * Created by 1 at 2022-09-13 19:35:56
+ * 实体【[定时任务](SYS_JOB)】的缓存类
+ */
+@SwCache(ident = "SYS_JOB", title = "定时任务")
+public class JobCache extends AbstractEntityCache {
+ //缓存key:按编码
+ public final static String mk_code = "code";
+
+ public static JobCache getInstance() {
+ return CacheManager.getIntance().getCache(JobCache.class);
+ }
+
+ public JobCache() {
+ //缓存key:按编码
+ regMap(mk_code, "sj_code");
+ }
+
+ //缓存key:按编码
+ public final JobEntity getByCode(String key) {
+ return getByKey(mk_code, key);
+ }
+
+}
diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobEntity.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobEntity.java
new file mode 100644
index 0000000..b7ec032
--- /dev/null
+++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobEntity.java
@@ -0,0 +1,81 @@
+package cc.smtweb.system.bpm.web.sys.base.job;
+
+import cc.smtweb.framework.core.annotation.SwTable;
+import cc.smtweb.framework.core.db.impl.DefaultEntity;
+
+/**
+ * Created by 1 at 2022-09-13 19:35:56
+ * 实体【[定时任务](SYS_JOB)】的Entity类
+ */
+@SwTable("SYS_JOB")
+public class JobEntity extends DefaultEntity {
+ public static final String ENTITY_NAME = "SYS_JOB";
+
+ public JobEntity() {
+ super(ENTITY_NAME);
+ }
+
+ /** 主键 */
+ public long getId() {
+ return getLong("sj_id");
+ }
+
+ /** 主键 */
+ public void setId(long sj_id) {
+ put("sj_id", sj_id);
+ }
+ /** 编码 */
+ public String getCode() {
+ return getStr("sj_code");
+ }
+
+ /** 编码 */
+ public void setCode(String sj_code) {
+ put("sj_code", sj_code);
+ }
+ /** 名称 */
+ public String getName() {
+ return getStr("sj_name");
+ }
+
+ /** 名称 */
+ public void setName(String sj_name) {
+ put("sj_name", sj_name);
+ }
+ /** 执行类的路径 */
+ public String getExeClass() {
+ return getStr("sj_exe_class");
+ }
+
+ /** 执行类的路径 */
+ public void setExeClass(String sj_exe_class) {
+ put("sj_exe_class", sj_exe_class);
+ }
+ /** cron表达式 */
+ public String getCron() {
+ return getStr("sj_cron");
+ }
+
+ /** cron表达式 */
+ public void setCron(String sj_cron) {
+ put("sj_cron", sj_cron);
+ }
+ /** 是否启用 */
+ public boolean isEnable() {
+ return getBool("sj_enable");
+ }
+
+ /** 是否启用 */
+ public void setEnable(boolean sj_enable) {
+ setBool("sj_enable", sj_enable);
+ }
+ /** 备注 */
+ public String getRemark() {
+ return getStr("sj_remark");
+ }
+
+ /** 备注 */
+ public void setRemark(String sj_remark) {
+ put("sj_remark", sj_remark);
+ }
+}
diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobLog.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobLog.java
new file mode 100644
index 0000000..9d8e5a9
--- /dev/null
+++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobLog.java
@@ -0,0 +1,102 @@
+package cc.smtweb.system.bpm.web.sys.base.job;
+
+import cc.smtweb.framework.core.annotation.SwTable;
+import cc.smtweb.framework.core.common.SwMap;
+import cc.smtweb.framework.core.db.impl.DefaultEntity;
+
+/**
+ * Created by 1 at 2022-09-14 10:09:03
+ * 实体【[定时任务执行日志](SYS_JOB_LOG)】的Entity类
+ */
+@SwTable("SYS_JOB_LOG")
+public class JobLog extends DefaultEntity {
+ public static final String ENTITY_NAME = "SYS_JOB_LOG";
+
+ public JobLog() {
+ super(ENTITY_NAME);
+ }
+
+ /**
+ * 主键
+ */
+ public long getId() {
+ return getLong("sjl_id");
+ }
+
+ /**
+ * 主键
+ */
+ public void setId(long sjl_id) {
+ put("sjl_id", sjl_id);
+ }
+
+ /**
+ * 任务id
+ */
+ public long getSjId() {
+ return getLong("sjl_sj_id");
+ }
+
+ /**
+ * 任务id
+ */
+ public void setSjId(long sjl_sj_id) {
+ put("sjl_sj_id", sjl_sj_id);
+ }
+
+ /**
+ * 开始时间
+ */
+ public long getBeginTime() {
+ return getLong("sjl_begin_time");
+ }
+
+ /**
+ * 开始时间
+ */
+ public void setBeginTime(long sjl_begin_time) {
+ put("sjl_begin_time", sjl_begin_time);
+ }
+
+ /**
+ * 完成时间
+ */
+ public long getEndTime() {
+ return getLong("sjl_end_time");
+ }
+
+ /**
+ * 完成时间
+ */
+ public void setEndTime(long sjl_end_time) {
+ put("sjl_end_time", sjl_end_time);
+ }
+
+ /**
+ * 是否成功
+ */
+ public boolean isSuccess() {
+ return getBool("sjl_success");
+ }
+
+ /**
+ * 是否成功
+ */
+ public void setSuccess(boolean sjl_success) {
+ setBool("sjl_success", sjl_success);
+ }
+
+ /**
+ * 执行情况
+ */
+ public String getInfo() {
+ return getStr("sjl_info");
+ }
+
+ /**
+ * 执行情况
+ */
+ public void setInfo(String sjl_info) {
+ put("sjl_info", sjl_info);
+ }
+}
diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobUtils.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobUtils.java
new file mode 100644
index 0000000..ca10395
--- /dev/null
+++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/job/JobUtils.java
@@ -0,0 +1,113 @@
+package cc.smtweb.system.bpm.web.sys.base.job;
+
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.*;
+import org.quartz.impl.StdSchedulerFactory;
+
+import java.util.*;
+
+/**
+ * Created by Akmm at 13-2-27 下午9:32
+ * 定时任务工厂
+ */
+@Slf4j
+public class JobUtils {
+ private static Scheduler scheduler = null;
+ private static JobUtils instance = null;
+ private Map mapJob = new HashMap<>();
+
+
+ public static Scheduler getScheduler() {
+ return scheduler;
+ }
+
+ public static JobUtils getInstance() {
+ if (instance == null) {
+ synchronized (JobUtils.class) {
+ if (instance == null) {
+ instance = new JobUtils();
+ }
+ }
+ }
+ return instance;
+ }
+
+ private JobUtils() {
+ try {
+ SchedulerFactory schedulerFactory = new StdSchedulerFactory();
+ scheduler = schedulerFactory.getScheduler();
+ } catch (Exception e) {
+ log.error("计划任务初始化失败", e);
+ e.printStackTrace();
+ }
+ }
+
+ //初始化所有任务
+ private void initJob() throws Exception {
+ Collection list = JobCache.getInstance().getAll();
+ for (JobEntity job : list) {
+ if (job.isEnable()) {
+ addJob(job);
+ }
+ }
+
+ }
+
+ public void start() {
+ try {
+ clear();
+ if (!scheduler.isStarted()) scheduler.start();
+ initJob();
+ } catch (Exception e) {
+ log.error("计划任务开始失败", e);
+ e.printStackTrace();
+ }
+ }
+
+ public void stop() {
+ try {
+ if (!scheduler.isShutdown()) {
+ clear();
+ scheduler.shutdown();
+ }
+ } catch (Exception e) {
+ log.error("计划任务开始失败", e);
+ e.printStackTrace();
+ }
+ }
+
+ public void clear() throws SchedulerException {
+ for (JobEntity job : mapJob.values()) {
+ try {
+ deleteJob(job);
+ } catch (Exception e) {
+ log.debug("任务" + job.getId() + "删除失败!");
+ }
+ }
+ }
+
+ //添加任务
+ public synchronized void addJob(JobEntity job) throws Exception {
+ String jobId = String.valueOf(job.getId());
+ JobDetail jobDetail = JobBuilder.newJob((Class extends org.quartz.Job>) Class.forName(job.getExeClass()))
+ .withIdentity(jobId).build();
+ jobDetail.getJobDataMap().put("job", job);
+ // 按新的cronExpression表达式构建一个新的trigger
+ CronTrigger trigger = TriggerBuilder.newTrigger()
+ .withIdentity(jobId)
+ .startNow()
+ .withSchedule(CronScheduleBuilder.cronSchedule(job.getCron()))
+ .build();
+
+ scheduler.scheduleJob(jobDetail, trigger);
+ }
+
+ //删除任务
+ public synchronized void deleteJob(JobEntity job) throws Exception {
+ String jobId = String.valueOf(job.getId());
+
+ scheduler.pauseTrigger(TriggerKey.triggerKey(jobId));
+ scheduler.unscheduleJob(TriggerKey.triggerKey(jobId));
+ scheduler.deleteJob(JobKey.jobKey(jobId));
+ }
+}
diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/oneTimeService/OneTimeTaskCleanService.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/oneTimeService/OneTimeTaskCleanService.java
index a7c9c7e..66dbf6c 100644
--- a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/oneTimeService/OneTimeTaskCleanService.java
+++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/oneTimeService/OneTimeTaskCleanService.java
@@ -21,8 +21,8 @@ public class OneTimeTaskCleanService extends BaseSysService {
}
@Override
- public void work() throws Exception {
+ public void work() {
String t = DateUtil.getNowYm() + "01000000";
- DbEngine.getInstance().update("delete from " + EntityHelper.getSchemaTableName(OnetimeTask.ENTITY_NAME) + " where statu=? and create_time", OneTimeStatu.SUCCESS.value, t);
+ DbEngine.getInstance().update("delete from " + EntityHelper.getSchemaTableName(OnetimeTask.ENTITY_NAME) + " where sot_statu=? and sot_create_time", OneTimeStatu.SUCCESS.value, t);
}
}
diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/CoreApplicationClosedListener.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/CoreApplicationClosedListener.java
new file mode 100644
index 0000000..99b94a5
--- /dev/null
+++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/CoreApplicationClosedListener.java
@@ -0,0 +1,34 @@
+package cc.smtweb.framework.core;
+
+import cc.smtweb.framework.core.common.SwConsts;
+import cc.smtweb.framework.core.mvc.controller.IStartListener;
+import cc.smtweb.framework.core.mvc.controller.scan.ApplicationScanner;
+import cc.smtweb.framework.core.mvc.controller.scan.BeanManager;
+import cc.smtweb.framework.core.systask.SysServiceFactory;
+import cc.smtweb.framework.core.systask.WebStartedEvent;
+import lombok.SneakyThrows;
+import org.springframework.boot.context.event.ApplicationStartedEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.event.ContextClosedEvent;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * 服务停止监听
+ */
+@Component
+public class CoreApplicationClosedListener implements ApplicationListener {
+ @Override
+ public void onApplicationEvent(ContextClosedEvent event) {
+ SysServiceFactory.getInstance().stop();
+ List list = BeanManager.getInstance().getStartListeners();
+ list.sort(Comparator.comparingInt(IStartListener::order));
+ for (IStartListener sl : list) {
+ sl.close();
+ }
+ }
+}
diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/CoreApplicationStartedListener.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/CoreApplicationStartedListener.java
index 629b789..822539d 100644
--- a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/CoreApplicationStartedListener.java
+++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/CoreApplicationStartedListener.java
@@ -4,6 +4,7 @@ import cc.smtweb.framework.core.common.SwConsts;
import cc.smtweb.framework.core.mvc.controller.IStartListener;
import cc.smtweb.framework.core.mvc.controller.scan.ApplicationScanner;
import cc.smtweb.framework.core.mvc.controller.scan.BeanManager;
+import cc.smtweb.framework.core.systask.SysServiceFactory;
import cc.smtweb.framework.core.systask.WebStartedEvent;
import lombok.SneakyThrows;
import org.springframework.boot.context.event.ApplicationStartedEvent;
@@ -38,6 +39,7 @@ public class CoreApplicationStartedListener implements ApplicationListener {
+ long time = System.currentTimeMillis();
+ if (isPrintLog()) {
+ log.debug(getTitle() + ":::开始执行.........");
+ }
+ work();
+ if (isPrintLog()) {
+ log.debug(getTitle() + ":::执行完成,耗时:" + (System.currentTimeMillis() - time) + "毫秒.........");
}
});
} catch (Exception e) {
@@ -42,5 +39,5 @@ public abstract class BaseSysService implements Runnable {
}
//主要要干的活
- protected abstract void work() throws Exception;
+ protected abstract void work();
}
diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/SingleRequestHelper.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/SingleRequestHelper.java
index 5997a52..d701938 100644
--- a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/SingleRequestHelper.java
+++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/SingleRequestHelper.java
@@ -8,15 +8,15 @@ import cc.smtweb.framework.core.util.StringUtil;
public class SingleRequestHelper {
public static interface ISingleWork {
- void doSingleWork() throws Exception;
+ void doSingleWork();
}
- public static void singleRequest(String region_key, String key, ISingleWork singleWork) throws Exception {
+ public static void singleRequest(String region_key, String key, ISingleWork singleWork) {
singleRequest(region_key, key, "其他人正在执行该操作,请等待!", singleWork);
}
- public static void singleRequest(String region_key, String key, String tip_msg, ISingleWork singleWork) throws Exception {
+ public static void singleRequest(String region_key, String key, String tip_msg, ISingleWork singleWork) {
boolean clearCache = false;
try {
String lastTime = RedisManager.getInstance().hGet(region_key, key, String.class);
diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/SysServiceFactory.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/SysServiceFactory.java
index bfa82d5..c90f6f8 100644
--- a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/SysServiceFactory.java
+++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/systask/SysServiceFactory.java
@@ -39,7 +39,7 @@ public class SysServiceFactory {
//启动任务
- protected void start() {
+ public void start() {
if (schedule != null) {
stop();
}
@@ -52,7 +52,7 @@ public class SysServiceFactory {
}
//停止任务
- protected void stop() {
+ public void stop() {
schedule.shutdown();
}
}