公司项目原先采用springmvc自带定时任务,新增一个定时任务时麻烦存在重复性工作而且不灵活没有页面展示。
废话不说,开干,定时任务数据配置存储在数据库
pom.xml
//加入Quartz依赖
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
spring.xml
<!-- C3P0数据库配置 -->
<bean id="sfDataSource_ex" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="5" />
<!-- 定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
<property name="acquireRetryAttempts" value="10" />
<!-- 两次连接中间隔时间,单位毫秒。Default: 1000 -->
<property name="acquireRetryDelay" value="1000" />
<!-- 连接关闭时默认将所有未提交的操作回滚。Default: false -->
<property name="autoCommitOnClose" value="false" />
<!-- 当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出 SQLException,如设为0则无限期等待。单位毫秒。Default: 0 -->
<property name="checkoutTimeout" value="50000" />
<!-- 每60秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod" value="60" />
<!-- 初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize" value="20" />
<!-- 连接池中保留的最小连接数 -->
<property name="minPoolSize" value="20" />
<!-- 连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="150" />
<!-- 最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="0" />
<!-- c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么 属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试 使用。Default: null -->
<property name="automaticTestTable" value="c3p0_TestTable" />
<!-- 获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效 保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试 获取连接失败后该数据源将申明已断开并永久关闭。Default: false -->
<property name="breakAfterAcquireFailure" value="false" />
</bean>
//数据源
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="sfDataSource_ex" />
</bean>
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />
<bean id="stdSchedulerFactory" class="org.quartz.impl.StdSchedulerFactory"></bean>
创建一个自己MyJobFactory实现AdaptableJobFactory接口的JobFactory类,并重写createJobInstance方法。
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;
@Component
public class MyJobFactory extends AdaptableJobFactory
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
// 调用父类的方法
Object jobInstance = super.createJobInstance(bundle);
// 进行注入
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
写一个service查询数据库配置
/**
* create by Li
* 2019/4/23 12:43
*/
@Service
public class QuartzService {
//jdbctemplate
@Autowired
SfSQLBaseService sfSQLBaseService;
public List getList(){
List list = sfSQLBaseService.queryForList("SELECT * FROM sf_task_manage");
return list;
}
public Map getInfo(String id){
Map map = sfSQLBaseService.queryForMap("SELECT * FROM sf_task_manage WHERE id="+id+"");
return map;
}
public void execute(String sql){
try {
sfSQLBaseService.execute(sql);
}catch (Exception e){
e.printStackTrace();
}
}
}
项目启动时启动servlet
import com.sf.utils.DateTimeUtils;
import org.quartz.Scheduler;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import java.util.List;
import java.util.Map;
/**
* quartz启动Servlet
* create by Li
* 2019/4/23 9:40
*
*/
public class QuartzStartServlet extends HttpServlet {
//定时任务启动基类
public static final String BASE_TASK_CLASS = "com.sf.tuxiaoer.scheduler.quartz.BaseTask";
public static final Logger logger = LoggerFactory.getLogger(QuartzStartServlet.class);
@Autowired
private StdSchedulerFactory stdSchedulerFactory;
@Autowired
QuartzService quartzService;
public void init() throws ServletException {
logger.info("开始任务");
WebApplicationContext ac = null;
try {
ServletContext sc = getServletContext();
ac = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
QuartzService quartzService = (QuartzService)ac.getBean("quartzService");
List list = quartzService.getList();
for(int i=0;i<list.size();i++){
Map _map = (Map)list.get(i);
String id = _map.get("id").toString();
Map map = quartzService.getInfo(id);
String task_name = map.get("task_name").toString();
String task_class = map.get("task_class").toString();
String cron_expression = map.get("cron_expression").toString();
stdSchedulerFactory = (StdSchedulerFactory)ac.getBean("stdSchedulerFactory");
Scheduler sche = stdSchedulerFactory.getScheduler();
//反射
Object baseClassObj = Class.forName(BASE_TASK_CLASS).newInstance();
try {
TaskUtil.addJob(sche, id,baseClassObj.getClass(),task_class, cron_expression);
logger.info("{}启动任务:{}",DateTimeUtils.getServerTime(),task_name);
quartzService.execute("UPDATE sf_task_manage SET istatus=1 WHERE id="+id+"");
}catch (Exception e){
e.printStackTrace();
quartzService.execute("UPDATE sf_task_manage SET istatus=0 WHERE id="+id+"");
logger.info("{}启动任务失败:{},原因:",DateTimeUtils.getServerTime(),task_name,e);
}
}
}catch (Exception e){
e.printStackTrace();
}
}
}
quartz定时任务工具类
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
/**
* quartz定时任务工具类
* create by Li
* 2019/4/22 16:01
*
*/
public class TaskUtil {
//默认任务组名
private static String JOB_GROUP_NAME = "JOB_GROUP_SYSTEM";
//默认触发器组名
private static String TRIGGER_GROUP_NAME = "TRIGGER_GROUP_SYSTEM";
//文件猴崽子
public static final String CLASS = ".class";
public static final Logger logger = LoggerFactory.getLogger(TaskUtil.class);
/**
* @Description: 添加一个定时任务
*
* @param sched
* 调度器
*
* @param jobName
* 任务名
* @param jobGroupName
* 任务组名
* @param triggerName
* 触发器名
* @param triggerGroupName
* 触发器组名
* @param jobClass
* 任务
* @param time
* 时间设置,参考quartz说明文档
*
* @Title: QuartzManager.java
*/
public static void addJob(Scheduler sched, String jobName, String jobGroupName, String triggerName, String triggerGroupName, @SuppressWarnings("rawtypes") Class jobClass, String time) {
try {
JobKey jobKey = new JobKey(jobName, jobGroupName);
@SuppressWarnings("unchecked") JobDetail jobDetail = newJob(jobClass).withIdentity(jobKey).build();
// 触发器
TriggerKey triggerKey = new TriggerKey(triggerName, triggerGroupName);
Trigger trigger = newTrigger().withIdentity(triggerKey).withSchedule(cronSchedule(time)).build();
sched.scheduleJob(jobDetail, trigger);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 修改一个任务的触发时间
*
* @param sched
* 调度器 *
* @param sched
* 调度器
* @param triggerName
* @param triggerGroupName
* @param time
*
* @Title: QuartzManager.java
*/ public static void modifyJobTime(Scheduler sched, String triggerName, String triggerGroupName, String time) {
try {
TriggerKey triggerKey = new TriggerKey(triggerName, triggerGroupName);
CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
if (trigger == null) { return; }
String oldTime = trigger.getCronExpression();
if (!oldTime.equalsIgnoreCase(time)) {
// 修改时间
trigger.getTriggerBuilder().withSchedule(cronSchedule(time));
// 重启触发器
sched.resumeTrigger(triggerKey);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 移除一个任务
*
* @param sched
* 调度器
* @param jobName
* @param jobGroupName
* @param triggerName
* @param triggerGroupName
*
* @Title: QuartzManager.java
*/ public static void removeJob(Scheduler sched, String jobName, String jobGroupName, String triggerName, String triggerGroupName) {
try {
TriggerKey triggerKey = new TriggerKey(triggerName, triggerGroupName);
sched.pauseTrigger(triggerKey);
// 停止触发器
sched.unscheduleJob(triggerKey);
// 移除触发器
JobKey jobKey = new JobKey(jobName, jobGroupName);
// 删除任务
sched.deleteJob(jobKey);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description:启动所有定时任务
*
* @param sched
* 调度器
*
* @Title: QuartzManager.java
*/ public static void startJobs(Scheduler sched) {
try {
sched.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description:关闭所有定时任务
*
* @param sched
* 调度器
*
*/ public static void shutdownJobs(Scheduler sched) {
try {
if (!sched.isShutdown()) {
sched.shutdown();
}
} catch (Exception e)
{ throw new RuntimeException(e);
}
}
/**
* @Description: 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名
*
* @param sched
* 调度器
*
* @param jobName
* 任务名
* @param base_class
*
* @param _class
* 任务
* @param time
* 时间设置,参考quartz说明文档
*
* @Title: QuartzManager.java
*/ public static void addJob(Scheduler sched, String jobName, @SuppressWarnings("rawtypes") Class base_class,String _class, String time) {
try {
JobKey jobKey = new JobKey(jobName, JOB_GROUP_NAME);
// 任务名,任务组,任务执行类
@SuppressWarnings("unchecked")
JobDetail jobDetail = newJob(base_class).withIdentity(jobKey).withDescription(_class).build();
TriggerKey triggerKey = new TriggerKey(jobName, TRIGGER_GROUP_NAME);
// 触发器
Trigger trigger = newTrigger().withIdentity(triggerKey).withSchedule(cronSchedule(time)).build();
// 触发器时间设定
sched.scheduleJob(jobDetail, trigger);
if (!sched.isShutdown())
{
sched.start();// 启动
}
} catch (Exception e) { throw new RuntimeException(e); } }
/**
* @Description: 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名)
*
* @param sched
* 调度器
* @param jobName
* @param time
*
* @Title: QuartzManager.java
*/ @SuppressWarnings("rawtypes") public static void modifyJobTime(Scheduler sched, String jobName, String time) {
try {
TriggerKey triggerKey = new TriggerKey(jobName, TRIGGER_GROUP_NAME);
CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
if (trigger == null) { return; }
String oldTime = trigger.getCronExpression();
if (!oldTime.equalsIgnoreCase(time)) {
JobKey jobKey = new JobKey(jobName, JOB_GROUP_NAME);
JobDetail jobDetail = sched.getJobDetail(jobKey);
Class objJobClass = jobDetail.getJobClass();
removeJob(sched, jobName);
logger.info("修改任务:" + jobName);
addJob(sched, jobName, objJobClass,jobDetail.getDescription(), time);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 移除一个任务(使用默认的任务组名,触发器名,触发器组名)
*
* @param sched
* 调度器
* @param jobName
*
* @Title: QuartzManager.java
*/ public static void removeJob(Scheduler sched, String jobName) {
try {
TriggerKey triggerKey = new TriggerKey(jobName, TRIGGER_GROUP_NAME);
sched.pauseTrigger(triggerKey);
// 停止触发器
sched.unscheduleJob(triggerKey);
// 移除触发器
JobKey jobKey = new JobKey(jobName, JOB_GROUP_NAME);
sched.deleteJob(jobKey); // 删除任务
} catch (Exception e) { throw new RuntimeException(e);
}
}}
定时任务基类BaseTask
/**
* 定时任务基类
* create by Li
* 2019/6/18 14:29
*/
import com.sf.tuxiaoer.service.SfSQLBaseService;
import com.sf.utils.DateTimeUtils;
import com.sf.utils.SFsmsQueue;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import java.text.SimpleDateFormat;
import java.util.concurrent.LinkedBlockingQueue;
public class BaseTask implements Job {
static WebApplicationContext content = ContextLoader.getCurrentWebApplicationContext();
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
Object classObj = null;
String previous_execute_time = "";
String execute_time = "";
String next_execute_time = "";
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("class:" + Class.forName(jobExecutionContext.getJobDetail().getDescription()).newInstance());
if(jobExecutionContext.getPreviousFireTime() != null){
previous_execute_time = simpleDateFormat.format(jobExecutionContext.getPreviousFireTime());
}
if(jobExecutionContext.getFireTime() != null){
execute_time = simpleDateFormat.format(jobExecutionContext.getFireTime());
}
if(jobExecutionContext.getNextFireTime() != null){
next_execute_time = simpleDateFormat.format(jobExecutionContext.getNextFireTime());
}
/* System.out.println("上次执行时间:" + next_execute_time);
System.out.println("当前执行时间:" + execute_time);
System.out.println("下次执行时间:" + next_execute_time);
System.out.println("执行次数:" + jobExecutionContext.getRefireCount());*/
String sql = "UPDATE sf_task_manage SET " +
" previou_execute_time='" + previous_execute_time + "',execute_time='" + execute_time + "'," +
" next_execute_time='" + next_execute_time + "' WHERE task_class='" + jobExecutionContext.getJobDetail().getDescription() + "'";
System.out.println("============="+sql);
SfSQLBaseService sfSQLBaseService = content.getBean(SfSQLBaseService.class);
sfSQLBaseService.execute(sql);
} catch (Exception e) {
e.printStackTrace();
}
try {
classObj = Class.forName(jobExecutionContext.getJobDetail().getDescription()).newInstance();
BaseScheduler baseScheduler = (BaseScheduler) content.getBean(classObj.getClass());
String bak_date = DateTimeUtils.getServerTime("yyyy-MM-dd");//系统时间
baseScheduler.execute();//不带参数
baseScheduler.execute(bak_date);//带日期参数
} catch (Exception e) {
e.printStackTrace();
}
}
定时任务执行基类
/**
* create by Li
* 2019/6/18 14:53
*
*/
public class BaseScheduler {
private String back_time;
public String getBack_time() {
return back_time;
}
public void setBack_time(String back_time) {
this.back_time = back_time;
}
//定时任务执行基类,所有执行任务继承此类
public void execute() throws Exception {
}
public void execute(String back_date) throws Exception {
this.back_time = back_date;
}
}
具体的某个执行任务
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.sf.tuxiaoer.scheduler.quartz.BaseScheduler;
import com.sf.tuxiaoer.service.SurchargeLogicService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.sf.tuxiaoer.service.SfSQLBaseService;
import com.sf.utils.DateTimeUtils;
import com.sf.utils.SendShortMessage;
/**
* create by Li
* 2019/6/18 9:18
*
*/
@Component
public class CreateLeaseByAutoImpl extends BaseScheduler {
private static Logger logger = LoggerFactory.getLogger(CreateLeaseByAutoImpl.class);
@Autowired
SfSQLBaseService sfSQLBaseService;
@Autowired
SurchargeLogicService surchargeLogicService;
public void execute() {
Date d = new Date();
int hours = d.getHours();
try {
String createTime = DateTimeUtils.getServerTime();
Map assignInfo = sfSQLBaseService.queryForMap("SELECT * FROM sf_wash_assign_code WHERE assign_time = "+hours+" ");
List shopList = sfSQLBaseService.queryForList("SELECT shop_name,shop_id,auto_create_lease_order_kind,shop_type,tu_coin FROM sf_shop_info " +
"WHERE auto_create_lease_order_time="+assignInfo.get("assign_id")+" AND auto_create_lease_order_flag=1 ");
if(shopList.size() > 0){
for(int i=0;i<shopList.size();i++){
Map map = (Map)shopList.get(i);
try {
int kinds = (int)map.get("auto_create_lease_order_kind");//0 按照上一笔完成洗涤单下同等数量租赁单; 1 多楼层按照配置模板下单
int shop_type = (int)map.get("shop_type");//兔币结算方式:0预付费;2后付费。
//可用库限数量
String usable_sql = " SElECT gs.goods_code,IFNULL(FORMAT(gs.stock_max*gs.stock_max_percent,0)-gs.stock-IFNULL(og.tmp_num,0),0) usable_num " +
" FROM sf_shop_goods_stock gs" +
" LEFT JOIN (SELECT og.goods_code,og.goods_name,SUM(og.rfid_logistics_num) tmp_num FROM sf_wash_order_goods og " +
" LEFT JOIN sf_wash_order o ON og.order_id=o.order_id" +
" WHERE o.istatus<12 AND o.wash_kinds=0 AND o.shop_id="+map.get("shop_id")+" GROUP BY og.goods_code) og ON gs.goods_code=og.goods_code" +
" LEFT JOIN sf_wash_goods_base g ON gs.goods_code=g.goods_code WHERE gs.shop_id="+map.get("shop_id")+" ";
String msg_content = "";//短信发送内容
String msg_sql = "SELECT IFNULL(tel,0) mobile,shop_id FROM sf_shop_info WHERE shop_id = "+map.get("shop_id")+" ";
Map msgMap = sfSQLBaseService.queryForMap(msg_sql);
String stock_msg_content = "";
String coin_msg_content = "";
String stock_floors = "";
String coin_floors = "";
if(kinds == 1){ //多模板多楼层
stock_msg_content = map.get("shop_name")+",由于您的库限不足,楼层[";
coin_msg_content = map.get("shop_name")+",由于您的兔币余额不足,楼层[";
String sql_select = "SELECT template_id,floor,total_num,shop_id FROM sf_wash_create_lease_order_template " +
"WHERE shop_id="+map.get("shop_id")+" AND kind=1 ";
List floorList = sfSQLBaseService.queryForList(sql_select);
double need_coin_total = 0.0;//需要的总兔币
for(int j=0;j<floorList.size();j++){
Map floorMap = (Map)floorList.get(j);
//当前楼层要下租赁单数量
String need_sql = "SELECT gt.goods_code,IFNULL(gt.num,0) need_num,td.price_wash_out,IFNULL(gt.num,0)*td.price_wash_out price_out" +
" FROM sf_wash_create_lease_order_goods_template gt " +
" LEFT JOIN sf_wash_create_lease_order_template t ON gt.template_id=t.template_id " +
" LEFT JOIN sf_shop_info s ON t.shop_id=s.shop_id " +
" LEFT JOIN sf_goods_price_template_detail td ON s.template_id=td.template_id AND gt.goods_code=td.goods_code " +
" WHERE t.template_id="+floorMap.get("template_id")+" AND gt.num>0 ";
List needList = sfSQLBaseService.queryForList(need_sql);//需要的
List usableList = sfSQLBaseService.queryForList(usable_sql);//可用的
double need_coin = 0.0;//需要兔币
//对比当前商品库限是否足够,不够的话直接跳过
boolean flag = true;
for(int x=0;x<needList.size();x++){
Map needMap = (Map)needList.get(x);//需要的
for(int y=0;y<usableList.size();y++){
Map usableMap = (Map)usableList.get(y);//可用的
//同一种商品 库限与下单数对比
if(needMap.get("goods_code").equals(usableMap.get("goods_code"))){
double _usable_num = Double.parseDouble(usableMap.get("usable_num").toString());
int usable_num = (int)_usable_num;
if(usable_num < 0){
usable_num = 0;
}
if(usable_num - Integer.parseInt(needMap.get("need_num").toString()) < 0){
flag = false;
need_coin = 0.0;//当前这笔订单库存不够,不下单 所需兔币清零
need_coin_total += need_coin;
stock_floors += floorMap.get("floor")+",";
break;
}else{
need_coin += (double)needMap.get("price_out");
need_coin_total += need_coin;//计算所需总兔币,用于跟现有兔币对比
flag = true;
}
}
}
if(flag == false){
break;
}
}
//预付费,计算当前订单所需兔币是否充足
if(shop_type == 0){
double tu_coin = (double)map.get("tu_coin");
Map dataMap = null;
double sumMoney = 0;
try {
//计算当前这笔订单附加费
dataMap = surchargeLogicService.deductMoney(Integer.parseInt(map.get("shop_id").toString()), 0);
sumMoney = (double)dataMap.get("money");
}catch (Exception e){
e.printStackTrace();
}
if(tu_coin - (need_coin_total+sumMoney) < 0){
coin_floors += floorMap.get("floor")+",";
flag = false;
}
}
if(flag == true){
String order_id = sfSQLBaseService.getWashOrderId();
String sql = "INSERT INTO sf_wash_order(order_id,wash_kinds,flag_sys_order," +
"shop_id,send_username,send_address,floor,send_mobile,istatus,chUserName,createTime," +
"paymentTime,num,rfid_logistics_total_num,logistics_total_num,rfid_factory_total_num," +
"factory_total_num,reserved) SELECT '"+order_id+"',0,1,shop_id," +
"contact,address,'"+floorMap.get("floor")+"',tel,1,'system','"+createTime+"','"+createTime+"'," +
""+floorMap.get("total_num")+","+floorMap.get("total_num")+","+floorMap.get("total_num")+"," +
""+floorMap.get("total_num")+","+floorMap.get("total_num")+",'根据订单模板"+floorMap.get("template_id")+"创建租赁单' " +
" FROM sf_shop_info WHERE shop_id="+floorMap.get("shop_id")+" ";
String sql_goods = "INSERT INTO sf_wash_order_goods(order_id,goods_code,goods_name,price_out," +
"num,total_price_out,rfid_logistics_num,logistics_num,rfid_factory_num,factory_num,createTime)" +
" SELECT '"+order_id+"',og.goods_code,b.goods_name,td.price_wash_out," +
"og.num,og.num*td.price_wash_out," +
"og.num,og.num,og.num,og.num,'"+createTime+"'" +
" FROM sf_wash_create_lease_order_goods_template og " +
" LEFT JOIN sf_wash_create_lease_order_template o ON og.template_id=o.template_id" +
" LEFT JOIN sf_shop_info s ON o.shop_id=s.shop_id" +
" LEFT JOIN sf_wash_goods_base b ON og.goods_code=b.goods_code " +
" LEFT JOIN sf_goods_price_template_detail td ON s.template_id=td.template_id AND og.goods_code=td.goods_code" +
" WHERE og.template_id='"+floorMap.get("template_id")+"' ";
try {
sfSQLBaseService.execute(sql);
sfSQLBaseService.execute(sql_goods);
String map_sql = "SELECT SUM(rfid_logistics_num) rfid_logistics_total_num,SUM(total_price_out) total_price_out" +
" FROM sf_wash_order_goods WHERE order_id='"+order_id+"' ";
Map orderMap = sfSQLBaseService.queryForMap(map_sql);
sfSQLBaseService.execute("UPDATE sf_wash_order SET num="+orderMap.get("rfid_logistics_total_num")+"," +
"rfid_logistics_total_num="+orderMap.get("rfid_logistics_total_num")+"," +
"logistics_total_num="+orderMap.get("rfid_logistics_total_num")+"," +
"rfid_factory_total_num="+orderMap.get("rfid_logistics_total_num")+"," +
"factory_total_num="+orderMap.get("rfid_logistics_total_num")+"," +
"total_price_out="+orderMap.get("total_price_out")+" WHERE order_id='"+order_id+"'");
try {
//插入附加费逻辑
int _num = surchargeLogicService.flagDeduct(Integer.parseInt(map.get("shop_id").toString()));
if(_num > 0 ){
String result = surchargeLogicService.mainDeductMoney(order_id, Integer.parseInt(map.get("shop_id").toString()), 0, "system");
logger.info("return:{}",result);
}
}catch (Exception e){
logger.error("fail:{}",e);
}
int num = sfSQLBaseService.queryForInt("SELECT count(*) FROM sf_wash_shop_logistics_route_operator WHERE shop_id="+floorMap.get("shop_id")+"");
if(num>0){
try{
assignInfo = sfSQLBaseService.queryForMap("SELECT ll.shop_id,ll.logistics_id,ll.laundry_id," +
"lr.route_id,lr.user_id FROM sf_wash_shop_logistics_laundry AS ll " +
"LEFT JOIN sf_wash_shop_logistics_route_operator AS lr ON(ll.shop_id=lr.shop_id) " +
"WHERE ll.shop_id="+floorMap.get("shop_id")+" AND lr.shop_id="+floorMap.get("shop_id")+"");
String assign_sql = "INSERT INTO sf_wash_order_assign(order_id,logistics_id,route_id,logistics_user_name,laundry_id)"
+ "VALUES('"+order_id+"',"+assignInfo.get("logistics_id")+","+assignInfo.get("route_id")+",'"+assignInfo.get("user_id")+"',"+assignInfo.get("laundry_id")+")";
sfSQLBaseService.execute(assign_sql);
sfSQLBaseService.execute("UPDATE sf_wash_order SET istatus=8,flag_assign=8,timeAssign='"+createTime+"' WHERE order_id='"+order_id+"'");
sfSQLBaseService.execute("UPDATE sf_wash_order_goods SET rfid_factory_num=num,rfid_logistics_num=num WHERE order_id='"+order_id+"'");
}catch (Exception e)
{e.printStackTrace();logger.error("error:{}",e);}
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
try {
if(stock_floors.length() > 0){
sendSMSMsg(msgMap.get("mobile").toString(),stock_msg_content+stock_floors.substring(0,stock_floors.lastIndexOf(",") )+"]自动下单失败,请知晓。");
}
if(coin_floors.length() > 0){
sendSMSMsg(msgMap.get("mobile").toString(),coin_msg_content+coin_floors.substring(0,coin_floors.lastIndexOf(",") )+"]自动下单失败,请知晓。");
}
}catch (Exception e){e.printStackTrace();}
}catch (Exception e){
e.printStackTrace();
logger.error("酒店未设置模板:{}",e);
}
}
}
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 发送短信
*/
private void sendSMSMsg(String mobile,String msg_content){
Map msgConfig = sfSQLBaseService.queryForMap("SELECT sf_key,sf_word,createTime,reserved FROM sf_key_word where sf_key = 'msg_url' ");
String msg_url = (String) msgConfig.get("sf_word");
msgConfig = sfSQLBaseService.queryForMap("SELECT sf_key,sf_word,createTime,reserved FROM sf_key_word where sf_key = 'msg_encode' ");
String msg_encode = (String) msgConfig.get("sf_word");
String send_msg_url = msg_url.replaceAll("\\{mobile\\}", mobile);
send_msg_url = send_msg_url.replaceAll("\\{content\\}", msg_content);
try {
String msg = SendShortMessage.sendMsg(send_msg_url,msg_encode);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
页面展示controller
import com.sf.tuxiaoer.scheduler.listener.TaskUtil;
import com.sf.tuxiaoer.web.BaseController;
import com.sf.tuxiaoer.web.SFSessionTools;
import com.sf.utils.DateTimeUtils;
import com.sf.utils.page.CurrentPage;
import com.sf.utils.page.PaginationHelper;
import net.sf.json.JSONArray;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
/**
* 定时任务配置管理
* create by Li
* 2018/12/12 20:31
*
*/
@Controller
public class TaskController extends BaseController {
@Autowired
private StdSchedulerFactory stdSchedulerFactory;
public static final Logger logger = LoggerFactory.getLogger(TaskController.class);
//任务启动基类
public static final String BASE_TASK_CLASS = "com.sf.tuxiaoer.scheduler.quartz.BaseTask";
@RequestMapping("/task/taskManageIndex")
public ModelAndView taskManageIndex(){
ModelAndView modelAndView = new ModelAndView();
String sql_select = "SELECT * FROM sf_task_manage WHERE 1=1 ORDER BY id ASC " ;
String sql_count = "SELECT COUNT(id) FROM sf_task_manage WHERE 1=1 ";
CurrentPage<HashMap> currentPageInfo = new PaginationHelper<HashMap>().fetchPage2(jdbcTemplate, sql_count, sql_select, request.getParameter("currentPage"));
modelAndView.addObject("currentPage", currentPageInfo.getCurrentPage());
modelAndView.addObject("totalCount", currentPageInfo.getTotalCount());
modelAndView.addObject("totalPage", currentPageInfo.getTotalPage());
modelAndView.addObject("taskList", currentPageInfo.getPageItems());
modelAndView.setViewName("/task/taskManageIndex");
return modelAndView;
}
@RequestMapping("/task/taskManageSave")
public void taskManageSave(HttpServletResponse response){
String task_name = request.getParameter("task_name");
String task_class = request.getParameter("task_class");
String cron_expression = request.getParameter("cron_expression");
// String task_id = request.getParameter("task_id");
String edit_user = SFSessionTools.getCurrentUserName();
String edit_time = DateTimeUtils.getServerTime("yyyy-MM-dd HH:mm:ss");
try {
String insert_sql = "INSERT INTO sf_task_manage(task_name,task_class,cron_expression,edit_user,edit_time)" +
"VALUES('"+task_name+"','"+task_class+"','"+cron_expression+"','"+edit_user+"','"+edit_time+"')";
sfSQLBaseService.execute(insert_sql);
PrintWriter out = response.getWriter();
Map map = new HashMap();
map.put("result", "新增成功");
String s = JSONArray.fromObject(map).toString();
out.print(s);
out.close();
}catch (Exception e){
e.printStackTrace();
}
}
@RequestMapping("/task/taskManageEdit")
public void taskManageEdit(HttpServletResponse response){
}
@RequestMapping("/task/taskManageDel")
public void taskManageDel(HttpServletResponse response){
}
/**
* 启动任务
* */
@RequestMapping("/task/addJob")
public void addJob(HttpServletResponse response) throws ClassNotFoundException, SchedulerException {
try {
String task_id = request.getParameter("task_id");
Map map = sfSQLBaseService.queryForMap("SELECT * FROM sf_task_manage WHERE id="+task_id+" ");
Scheduler sche = stdSchedulerFactory.getScheduler();
//反射
Object baseClassObj = Class.forName(BASE_TASK_CLASS).newInstance();
TaskUtil.addJob(sche, task_id,baseClassObj.getClass(),map.get("task_class").toString(), map.get("cron_expression").toString());
PrintWriter out = response.getWriter();
out.print("启动成功");
logger.info("操作员[{}],{}启动任务:{}",SFSessionTools.getCurrentUserName(),DateTimeUtils.getServerTime(),map.get("task_name"));
sfSQLBaseService.execute("UPDATE sf_task_manage SET istatus=1," +
"edit_user='"+SFSessionTools.getCurrentUserName()+"',edit_time='"+DateTimeUtils.getServerTime()+"' WHERE id="+task_id+"");
out.close();
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 修改任务
* */
@RequestMapping("/task/editJob")
public void editJob(HttpServletResponse response) throws ClassNotFoundException, SchedulerException {
try {
String task_id = request.getParameter("task_id");
String cron_expression = request.getParameter("cron_expression");
String task_name = request.getParameter("task_name");
Map map = sfSQLBaseService.queryForMap("SELECT * FROM sf_task_manage WHERE id="+task_id+" ");
Scheduler sche = stdSchedulerFactory.getScheduler();
TaskUtil.modifyJobTime(sche, task_id,cron_expression);
PrintWriter out = response.getWriter();
sfSQLBaseService.execute("UPDATE sf_task_manage SET cron_expression='"+cron_expression+"',task_name='"+task_name+"'," +
"edit_user='"+SFSessionTools.getCurrentUserName()+"',edit_time='"+DateTimeUtils.getServerTime()+"' WHERE id="+task_id+"");
out.print("修改成功");
logger.info("操作员[{}],{}修改任务:{}",SFSessionTools.getCurrentUserName(),DateTimeUtils.getServerTime(),map.get("task_name"));
out.close();
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 立即执行任务
* */
@RequestMapping("/task/startJob")
public void startJob(HttpServletResponse response) throws ClassNotFoundException, SchedulerException {
try {
String task_id = request.getParameter("task_id");
Map map = sfSQLBaseService.queryForMap("SELECT * FROM sf_task_manage WHERE id="+task_id+" ");
Scheduler scheduler = stdSchedulerFactory.getScheduler();
JobKey jobKey = JobKey.jobKey(task_id, "JOB_GROUP_SYSTEM");
scheduler.triggerJob(jobKey);
PrintWriter out = response.getWriter();
sfSQLBaseService.execute("UPDATE sf_task_manage SET "+
"edit_user='"+SFSessionTools.getCurrentUserName()+"',edit_time='"+DateTimeUtils.getServerTime()+"' WHERE id="+task_id+"");
out.print("任务执行成功");
logger.info("操作员[{}],{}执行任务:{}",SFSessionTools.getCurrentUserName(),DateTimeUtils.getServerTime(),map.get("task_name"));
out.close();
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 关闭任务
* */
@RequestMapping("/task/removeJob")
public void removeJob(HttpServletResponse response) throws ClassNotFoundException, SchedulerException {
try {
String task_id = request.getParameter("task_id");
Map map = sfSQLBaseService.queryForMap("SELECT * FROM sf_task_manage WHERE id="+task_id+" ");
Scheduler sche = stdSchedulerFactory.getScheduler();
TaskUtil.removeJob(sche, task_id);
PrintWriter out = response.getWriter();
logger.info("操作员[{}],{}关闭任务:{}",SFSessionTools.getCurrentUserName(),DateTimeUtils.getServerTime(),map.get("task_name"));
out.print("关闭成功");
sfSQLBaseService.execute("UPDATE sf_task_manage SET istatus=0," +
"edit_user='"+SFSessionTools.getCurrentUserName()+"',edit_time='"+DateTimeUtils.getServerTime()+"' WHERE id="+task_id+"");
out.close();
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 批量新增任务
* */
@RequestMapping("/task/addBatch")
public void addBatch(HttpServletResponse response) throws ClassNotFoundException, SchedulerException {
try {
String inputInfo = request.getParameter("inputInfo");
String[] datas = inputInfo.split("\\|");
for(int i=0;i<datas.length;i++){
String[] prams = datas[i].split("@");
String task_name = prams[0];
String task_class = prams[1];
String cron_expression = prams[2];
sfSQLBaseService.execute("INSERT INTO sf_task_manage(task_name,task_class,cron_expression,istatus,edit_user,edit_time)" +
"VALUES('"+task_name+"','"+task_class+"','"+cron_expression+"',0,'"+SFSessionTools.getCurrentUserName()+"','"+DateTimeUtils.getServerTime()+"')");
}
PrintWriter out = response.getWriter();
out.print("操作成功");
out.close();
}catch (Exception e){
e.printStackTrace();
}
}
页面展示
<%--
Created by IntelliJ IDEA.
User: Li
Date: 2018/12/12
Time: 20:30
To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<head>
<title></title>
<style type="text/css">
/*弹出层的STYLE*/
html,body {height:100%; margin:0px; font-size:12px;}
.mydiv {
-moz-border-radius: 16px;
-webkit-border-radius: 16px;
border-radius: 16px;
background-color:lavender;
/* text-align: center;*/
z-index:99;
width:55%;
height: auto;
left:30%;/*FF IE7*/
top: 10%;/*FF IE7*/
margin-left:-130px!important;/*FF IE7 该值为本身宽的一半 */
margin-top:-20px!important;/*FF IE7 该值为本身高的一半*/
margin-top:0px;
position:fixed!important;/*FF IE7*/
position:absolute;/*IE6*/
}
.bg {
background-color: #878b80;
width: 100%;
height: 100%;
left:0;
top:0;/*FF IE7*/
filter:alpha(opacity=50);/*IE*/
opacity:0.5;/*FF*/
z-index:1;
position:fixed!important;/*FF IE7*/
position:absolute;/*IE6*/
}
/*The END*/
</style>
</head>
<body>
<div>
<ul class="breadcrumb">
<li>
<a href="<%=basePath %>task/taskManageIndex">定时任务管理</a>
</li>
<li class="pull-right glyphicon">
<a class="btn-flat success plus" href="javascript:void(0);" onclick="addTask()">+新增定时任务</a>
</li>
</ul>
</div>
<div style="margin-left: 10%;" id="infoBox"></div>
<div class="box-content">
<table class="table table-striped table-bordered table-condensed table-hover responsive">
<thead>
<tr>
<th width="20%">任务别名</th>
<th width="20%">任务CLASS</th>
<th width="16%">任务时间</th>
<th width="6%">任务状态</th>
<th width="8%">编辑人</th>
<th width="10%">编辑时间</th>
<th width="20%">操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${taskList}" var="task">
<tr class="odd gradeX">
<td><input type="text" class="form-control" id="${task.id}task_name" value="${task.task_name}"></td>
<%-- <td>${task.task_id}</td>--%>
<td>${task.task_class}</td>
<td><input type="text" class="form-control" id="${task.id}expression" value="${task.cron_expression}"></td>
<td>
<c:choose>
<c:when test="${task.istatus == 0}">
<span class="label-default label label-danger">停止</span>
</c:when>
<c:when test="${task.istatus == 1}">
<span class="label-default label label-success">运行</span>
</c:when>
</c:choose>
</td>
<td>${task.edit_user}</td>
<td>${task.edit_time}</td>
<td>
<c:if test="${task.istatus == 0}">
<a id="edit${task.id}" class="btn-sm btn-info" href="javascript:void(0);" onclick="addJob(${task.id})">
<i class="glyphicon glyphicon-edit icon-white"></i>启动
</a>
|
</c:if>
<a id="edit${task.id}" class="btn-sm btn-info" href="javascript:void(0);" onclick="editJob(${task.id})">
<i class="glyphicon glyphicon-edit icon-white"></i>编辑
</a>
<c:if test="${task.istatus == 1}">
|
<a id="edit${task.id}" class="btn-sm btn-info" href="javascript:void(0);" onclick="startJob(${task.id})">
<i class="glyphicon glyphicon-edit icon-white"></i>立即执行
</a>
|
<a id="remove${task.id}" class="btn-sm btn-info" href="javascript:void(0);" onclick="removeJob(${task.id})">
<i class="glyphicon glyphicon-edit icon-white"></i>关闭
</a>
</c:if>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<div id="popDiv" class="mydiv" style="display:none;">
<br><br>
<center><b style="font-size: 18px;">新增定时任务</b><br><br></center>
<table style="width: 400px;margin-left: 10%;text-align: center">
<tr>
<td>任务别名</td>
<td>
<input type="text" id="task_name" class="form-control" placeholder="任务别名"><td>
</td>
</td>
</tr>
<tr>
<td>任务CLASS</td>
<td>
<input type="text" id="task_class" class="form-control" placeholder="任务CLASS">
</td>
</tr>
<tr>
<td>任务时间</td>
<td>
<input type="text" id="cron_expression" class="form-control" placeholder="任务时间"><a href="javascript:void(0);">cronExpression表达式参照----------------------------></a>
</td>
</tr>
<tr>
<td>新增</td><td><textarea type="text" class="form-control" id="inputInfo" rows="10" cols="10"></textarea></td><td><a href="javascript:void(0);" onclick="addBatch()">批量新增</a></td>
</tr>
</table>
<p style="margin-top: -180px;margin-left: 520px;color: red">
0 0 12 * * ? 每天12点触发<br>
0 15 10 ? * * 每天10点15分触发<br>
0 15 10 * * ? 每天10点15分触发<br>
0 15 10 * * ? * 每天10点15分触发<br>
0 15 10 * * ? 2005 2005年每天10点15分触发<br>
0 * 14 * * ? 每天下午的 2点到2点59分每分触发<br>
0 0/5 14 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发)<br>
0 0/5 14,18 * * ? 每天下午的 2点到2点59分、18点到18点59分(整点开始,每隔5分触发)<br>
0 0-5 14 * * ? 每天下午的 2点到2点05分每分触发<br>
0 10,44 14 ? 3 WED 3月分每周三下午的 2点10分和2点44分触发<br>
0 15 10 ? * MON-FRI 从周一到周五每天上午的10点15分触发<br>
0 15 10 15 * ? 每月15号上午10点15分触发<br>
0 15 10 L * ? 每月最后一天的10点15分触发<br>
0 15 10 ? * 6L 每月最后一周的星期五的10点15分触发<br>
0 15 10 ? * 6L 2002-2005 从2002年到2005年每月最后一周的星期五的10点15分触发<br>
0 15 10 ? * 6#3 每月的第三周的星期五开始触发<br>
0 0 12 1/5 * ? 每月的第一个中午开始每隔5天触发一次<br>
0 11 11 11 11 ? 每年的11月11号 11点11分触发(光棍节)<br>
</p>
<br><br>
<input type="button" style="margin-top: -200px;margin-left:60px;width: 20%;height: 33px" value="新增" onclick="saveTask()"> <input type="button" style="width: 20%;height: 33px" value="关闭" onclick="closeDiv(0)">
<br><br>
<br><br>
</div>
<div id="bg" class="bg" style="display:none;"></div>
<script>
var errInfo = '${errInfo}';
$(document).ready(function(){
if(errInfo!='null'&& errInfo!=''){
$("#infoBox").tips({
side:1,
msg:errInfo,
bg:'#FF5080',
time:10
});
}
$("#infoBox").focus();
});
function addTask(){
$(".bg").fadeIn(1000);
$("#popDiv").animate({
height:'toggle'
});
}
function saveTask(){
var task_id = $("#task_id").val();
var task_name = $("#task_name").val();
var task_class = $("#task_class").val();
var cron_expression = $("#cron_expression").val();
if(task_name == "" || task_class == "" || cron_expression == "" || task_id == ""){
$("#infoBox").tips({
side:1,
msg:'设置不可空',
bg:'#FF5080',
time:10
});
return;
}
BootstrapDialog.confirm('确认新增定时任务?谨慎操作', function(result){
if(result){
var data = "task_name="+task_name+"&task_class="+task_class+"&cron_expression="+cron_expression;
$.ajax({
url:'<%=basePath %>task/taskManageSave',
type:'post',
data:data,
success:function(data){
var objs = jQuery.parseJSON(data);
alert(objs[0].result);
window.location.href = "<%=basePath %>task/taskManageIndex";
}
});
}else{
return;
}
});
}
function addJob(task_id){
BootstrapDialog.confirm('确认启动定时任务?谨慎操作', function(result){
if(result){
$.ajax({
url:'<%=basePath %>task/addJob',
type:'post',
data:'task_id='+task_id,
success:function(data){
alert(data);
location.href="<%=basePath %>task/taskManageIndex";
}
});
}else{
return;
}
});
}
function editJob(task_id){
var cron_expression = $("#"+task_id+"expression").val();
var task_name = $("#"+task_id+"task_name").val();
if(cron_expression == "" || task_name == ""){
alert("不可为空");
return;
}
BootstrapDialog.confirm('确认修改定时任务?谨慎操作', function(result){
if(result){
var data = "task_id="+task_id+"&cron_expression="+cron_expression+"&task_name="+task_name;
$.ajax({
url:'<%=basePath %>task/editJob',
type:'post',
data:data,
success:function(data){
alert(data);
location.href="<%=basePath %>task/taskManageIndex";
}
});
}else{
return;
}
});
}
function removeJob(task_id){
BootstrapDialog.confirm('确认关闭定时任务?谨慎操作', function(result){
if(result){
$.ajax({
url:'<%=basePath %>task/removeJob',
type:'post',
data:'task_id='+task_id,
success:function(data){
alert(data);
location.href="<%=basePath %>task/taskManageIndex";
}
});
}else{
return;
}
});
}
//立即启动
function startJob(task_id){
BootstrapDialog.confirm('确认执行定时任务?谨慎操作', function(result){
if(result){
var data = "task_id="+task_id;
$.ajax({
url:'<%=basePath %>task/startJob',
type:'post',
data:data,
success:function(data){
alert(data);
location.href="<%=basePath %>task/taskManageIndex";
}
});
}else{
return;
}
});
}
function addBatch(){
var inputInfo = $("#inputInfo").val();
$.ajax({
url:'<%=basePath %>task/addBatch',
type:'post',
data:'inputInfo='+inputInfo,
success:function(data){
alert(data);
}
});
}
function closeDiv(){
$("#popDiv").fadeOut(1000);
$(".bg").fadeOut(1000);
window.location.href = "<%=basePath %>task/taskManageIndex";
}
</script>
<script src="<%=basePath%>include/jquery.tips.js"></script>
</body>
</html>
定时任务配置的数据存储至数据库、至此,整套流程完成、后续新增定时任务只需创建一个任务执行类继承BaseScheduler,就大功告成了。
版权声明:本文为u012262640原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。