如何设计定时任务界面并通过代码开发苍穹定时任务原创
5人赞赏了该文章
2,535次浏览
编辑于2023年01月12日 16:36:25
在一个数据库巡检项目中,需要设置定时任务,能够按指定的时间重复或单次定期自动巡检,以下为设计的要点:
参考苍穹标准的定时任务界面进行设计,需要最终主要是生成cron表达式,通过cron表达式执行定时任务。
2.在“保存”项添加自定义定时任务服务插件
3.代码核心部分
//单据保存后产生或者修改调度任务、计划 public class ExecuteInspectPlanPlugin extends AbstractOperationServicePlugIn { @Override public void onPreparePropertys(PreparePropertysEventArgs e) { super.onPreparePropertys(e); for(String tmp : DatabaseInspectElement.CKWEEK) { e.getFieldKeys().add(tmp); } for(String tmp : DatabaseInspectElement.CKDATE) { e.getFieldKeys().add(tmp); } for(String tmp : DatabaseInspectElement.CKHOUR) { e.getFieldKeys().add(tmp); } e.getFieldKeys().add("id"); e.getFieldKeys().add("billno"); e.getFieldKeys().add("kdps_name"); e.getFieldKeys().add("kdps_db_connect"); e.getFieldKeys().add("kdps_company_code"); e.getFieldKeys().add("kdps_company_name"); e.getFieldKeys().add("kdps_starttime"); e.getFieldKeys().add("kdps_endtime"); e.getFieldKeys().add("kdps_plan"); } @Override public void onAddValidators(AddValidatorsEventArgs e) { e.addValidator(new ExecuteInspectPlanValidator()); } @Override public void afterExecuteOperationTransaction(AfterOperationArgs e) { super.afterExecuteOperationTransaction(e); DynamicObject[] passDataEntities = e.getDataEntities(); if(passDataEntities.length>0) { for(DynamicObject data :passDataEntities ) { if(data.getBoolean(DatabaseInspectElement.KDPS_TIME_EXECUTE)) { //解决定时任务的代码 String number = data.getString("billno"); Object JobId = ""; QFilter number_filter = new QFilter("number", QCP.equals, number); ScheduleHelper schhelper = new ScheduleHelper(); //存在相同编码的则更新调度作业,否则创建调度作业 if (QueryServiceHelper.exists(DatabaseInspectElement.SCH_JOB, new QFilter[]{number_filter})) { JobId = QueryServiceHelper.queryPrimaryKeys(DatabaseInspectElement.SCH_JOB, new QFilter[]{number_filter}, "id desc", 1).get(0); schhelper.updateJob(JobId, data); } else { JobId = schhelper.CreateJob(data); } Object scheduleId; QFilter job_filter = new QFilter("job", QCP.equals, JobId); //存在相同编码的则更新调度计划,否则创建调度计划 if (QueryServiceHelper.exists(DatabaseInspectElement.SCH_SCHEDULE, new QFilter[]{job_filter})) { scheduleId = QueryServiceHelper.queryPrimaryKeys(DatabaseInspectElement.SCH_SCHEDULE, new QFilter[]{job_filter}, "id desc", 1).get(0); schhelper.updateSchedule(scheduleId, data); } else { schhelper.CreateSchedule(JobId, data); } } } } } } class ExecuteInspectPlanValidator extends AbstractValidator { @Override public String getEntityKey() { return super.getEntityKey(); } @Override public void initializeConfiguration() { super.initializeConfiguration(); this.entityKey = DatabaseInspectElement.KDPS_DB_INSPECT; } @Override public void initialize() { super.initialize(); } @Override public void validate() { for (ExtendedDataEntity dataEntity : this.getDataEntities()) { DynamicObject doDbConnect = (DynamicObject) dataEntity.getValue("kdps_db_connect"); boolean isNew = ObjectUtils.isEmpty(doDbConnect.getPkValue()) ; //巡检任务,开始时间或者结束时间不能小于当天 if((boolean) dataEntity.getValue(DatabaseInspectElement.KDPS_TIME_EXECUTE)) { String kdps_repeatmode = (String) dataEntity.getValue(DatabaseInspectElement.KDPS_REPEATMODE); Date startdt = (Date) dataEntity.getValue("kdps_starttime"); Date enddt = (Date) dataEntity.getValue("kdps_endtime"); if(kdps_repeatmode == null || startdt == null || enddt == null){ this.addErrorMessage(dataEntity, "开启定时执行时,重复时间单位、开始执行时间、结束执行时间均不能为空,请检查!"); continue; } Date now = new Date(); if(enddt.before( new Date( startdt.getTime()+1*60*60*1000 )) ) { this.addErrorMessage(dataEntity, "结束时间应该大于开始时间+1小时"); continue; } if(ObjectUtils.isEmpty(startdt)) { this.addErrorMessage(dataEntity, "当为定时执行时,其[计划开始时间]不能为空"); continue; } if(ObjectUtils.isEmpty(enddt)) { this.addErrorMessage(dataEntity, "当为定时执行时,其[计划结束时间]不能为空"); continue; } if( isNew && startdt.before( now )) { this.addErrorMessage(dataEntity, "当为定时执行时,其[计划开始时间]不能小于现在"); continue; } if( isNew && enddt.before( now )) { this.addErrorMessage(dataEntity, "当为定时执行时,其[计划结束时间]不能小于现在"); continue; } } if( (boolean)dataEntity.getValue(DatabaseInspectElement.KDPS_TIME_EXECUTE) ) { if (StringUtils.isEmpty( (String) dataEntity.getValue(DatabaseInspectElement.KDPS_REPEATMODE))) { String ErrMsg = "在定时执行下,[重复时间单位]不能为空"; this.addErrorMessage(dataEntity, ErrMsg); continue; } //设置Cron表达式 String sec_yu = "0 "; String min_yu = "0 "; String date_yu = "? "; String week_yu = "? "; String month_yu = "* "; String hour_zy = ""; String date_zy = ""; String week_zy = ""; String plan = sec_yu + min_yu; String planbz = new String(); String planbz_w = new String(); //小时域的处理 for (int k = 0; k < DatabaseInspectElement.CKHOUR.length; k++) { if ((boolean) dataEntity.getValue(DatabaseInspectElement.CKHOUR[k])) { hour_zy += String.valueOf(k) + ","; } } //去掉最后的逗号 if (!(StringUtils.equalsIgnoreCase(hour_zy, ""))) { hour_zy = hour_zy.substring(0, hour_zy.length() - 1) + " "; } //日域的处理 for (int k = 0; k < DatabaseInspectElement.CKDATE.length; k++) { if ((boolean) dataEntity.getValue(DatabaseInspectElement.CKDATE[k])) { date_zy += String.valueOf(k + 1) + ","; } } //去掉最后的逗号 if (!(StringUtils.equalsIgnoreCase(date_zy, ""))) { date_zy = date_zy.substring(0, date_zy.length() - 1) + " "; } //星期域的处理 for (int k = 0; k < DatabaseInspectElement.CKWEEK.length; k++) { if ((boolean) dataEntity.getValue(DatabaseInspectElement.CKWEEK[k])) { week_zy += String.valueOf(k + 1) + ","; planbz_w += DatabaseInspectElement.weekToZhou.get(DatabaseInspectElement.CKWEEK[k]) + ","; } } //去掉最后的逗号 if (!(StringUtils.equalsIgnoreCase(week_zy, ""))) { week_zy = week_zy.substring(0, week_zy.length() - 1) + " "; planbz_w = planbz_w.substring(0, planbz_w.length() - 1); } //需要勾选小时 if ((StringUtils.equalsIgnoreCase(hour_zy, ""))) { this.addErrorMessage(dataEntity, "未勾选定时巡检执行的时间点,请补充完整"); continue; } String kdps_repeatmode = (String) dataEntity.getValue(DatabaseInspectElement.KDPS_REPEATMODE); //月 if (StringUtils.equalsIgnoreCase(kdps_repeatmode.toString(), "m")) { if ((StringUtils.equalsIgnoreCase(date_zy, ""))) { this.addErrorMessage(dataEntity, "当[重复时间单位]为[月]时,请至少选定一个日期"); continue; } plan += hour_zy + date_zy + month_yu + week_yu; planbz = "每月的[" + date_zy + "]日[" + hour_zy + "]时间执行"; } //星期 if (StringUtils.equalsIgnoreCase(kdps_repeatmode.toString(), "w")) { if ((StringUtils.equalsIgnoreCase(week_zy, ""))) { this.addErrorMessage(dataEntity, "当[重复时间单位]为[周]时,请至少选定一个[周几]"); continue; } plan += hour_zy + date_yu + month_yu + week_zy; planbz = "每周的[" + planbz_w + "]的[" + hour_zy + "]时间执行"; } //天 if (StringUtils.equalsIgnoreCase(kdps_repeatmode.toString(), "d")) { plan += hour_zy + "* " + month_yu + week_yu; planbz = "每天的[" + hour_zy + "]时间执行"; } String plan_tmp = ""; boolean timeExecute = (boolean) dataEntity.getValue(DatabaseInspectElement.KDPS_TIME_EXECUTE); //至少勾选小时, 结合星期几来考虑 if(timeExecute) { boolean isOk = true; for( String hour : DatabaseInspectElement.CKHOUR) { isOk = isOk && StringUtils.isEmpty( dataEntity.getValue(hour).toString() ); } if ( isOk) { this.addErrorMessage(dataEntity, "未勾选定时巡检执行的时间点,请补充完整"); continue; } isOk = true; if (StringUtils.equalsIgnoreCase(kdps_repeatmode.toString(), "w")) //星期 { for( String week : DatabaseInspectElement.CKWEEK ) { isOk = isOk && StringUtils.isEmpty( dataEntity.getValue(week).toString() ); if( isOk ) { this.addErrorMessage(dataEntity, "当[重复时间单位]为[周]时,请至少选定一个[周几]"); continue; } } } if (StringUtils.equalsIgnoreCase(kdps_repeatmode.toString(), "m")) //月份 { for( String date : DatabaseInspectElement.CKDATE ) { isOk = isOk && StringUtils.isEmpty( dataEntity.getValue(date).toString()); } if(isOk) { this.addErrorMessage(dataEntity, "当[重复时间单位]为[月]时,请至少选定一个日期"); continue; } } } plan_tmp = plan; try { DatabaseInspectElement.parser.parse(plan_tmp); } catch (Exception var8) { this.addErrorMessage(dataEntity, "计划时间设置错误"); } dataEntity.setValue("kdps_repeatbz", planbz); //执行周期 dataEntity.setValue("kdps_plan", plan); //cron表达式 } } } }
//执行计划辅助类(设置调度作业和调度计划) public class ScheduleHelper { //创建调度计划 public void CreateSchedule(Object jobId, DynamicObject data) { PlanInfo planInfo = new PlanInfo(); planInfo.setJobId(jobId.toString()); //采用巡检报告编码和名称 String billno = data.getString("billno"); String name = data.getString("kdps_name"); String phone = LittleHelperUtils.getUserPhoneById(((DynamicObject)data.get("creator")).get("id").toString()); planInfo.setNumber(billno); planInfo.setName(phone+"_"+name); //设置调度计划开始时间,自定义时间 Date kdps_starttime = (Date) data.get("kdps_starttime"); Calendar starttime = Calendar.getInstance(); starttime.setTime(kdps_starttime); planInfo.setStartTime(starttime); //设置调度计划结束时间,自定义时间 Date kdps_endtime = (Date) data.get("kdps_endtime"); Calendar endtime = Calendar.getInstance(); endtime.setTime(kdps_endtime); planInfo.setEndTime(endtime); //设置cron表达式,根据表达式解析重复执行的周期 String kdps_plan = (String) data.get("kdps_plan"); planInfo.setCronExpression(kdps_plan); //创建调度计划 DispatchServiceHelper.invokeBOSService( "JobDispatcher", "createPlan", planInfo); } //更新调度计划 public void updateSchedule(Object scheduleId, DynamicObject data) { DynamicObject schedule_data = BusinessDataServiceHelper.loadSingle(scheduleId, "sch_schedule"); String phone = LittleHelperUtils.getUserPhoneById(((DynamicObject)data.get("creator")).get("id").toString()); String name = data.getString("kdps_name"); schedule_data.set("name",phone+"_"+name); Date starttime = (Date) data.get("kdps_starttime"); schedule_data.set("starttime",starttime); Date endtime = (Date) data.get("kdps_endtime"); schedule_data.set("endtime",endtime); String kdps_plan = (String) data.get("kdps_plan"); schedule_data.set("plan",kdps_plan); SaveServiceHelper.save( new DynamicObject[] {schedule_data}); } //更新调度作业名称 public void updateJob(Object jobId, DynamicObject data) { DynamicObject job_data = BusinessDataServiceHelper.loadSingle(jobId, "sch_job"); String phone = LittleHelperUtils.getUserPhoneById(((DynamicObject)data.get("creator")).get("id").toString()); String name = data.getString("kdps_name"); job_data.set("name",phone+"_"+name); SaveServiceHelper.save( new DynamicObject[] {job_data} ); } //创建调度作业 public Object CreateJob(DynamicObject data) { Map<String, Object> param = new HashMap<String, Object>(); param.put("kdps_db_inspect_info", data.get("id")); //TimingDatabaseInspectTask的execute函数参数 String billno = data.getString("billno"); String name = data.getString("kdps_name"); String phone = LittleHelperUtils.getUserPhoneById(((DynamicObject)data.get("creator")).get("id").toString()); String taskClassname = "kdps.businessinspection.plugin.OMInspection.TimingDatabaseInspectTask"; long runByUserId = Long.parseLong(((DynamicObject)data.get("creator")).getPkValue().toString().trim()); //负责人 final String APPID = "kdps_business_inspection"; JobInfo job = new JobInfo(); job.setNumber(billno); job.setName(phone+"_"+name); job.setRunByUserId(runByUserId); job.setJobType(JobType.BIZ); job.setTaskClassname(taskClassname); job.setParams(param); job.setAppId(APPID); job.setRunConcurrently(false); //串行执行 // job.setStrategy("1"); //等待前一任务执行完毕 Object JobId = DispatchServiceHelper.invokeBOSService("JobDispatcher", "createJob", job); return JobId; } }
推荐阅读