如何设计定时任务界面并通过代码开发苍穹定时任务原创
金蝶云社区-彩虹之巅style
彩虹之巅style
5人赞赏了该文章 2,946次浏览 未经作者许可,禁止转载编辑于2023年01月12日 16:36:25
summary-icon摘要由AI智能服务提供

文本描述了一个数据库巡检项目中定时任务的设计和实现。项目需要设置定时任务,以支持按指定时间重复或单次自动巡检。设计要点包括参考苍穹标准的定时任务界面设计,并生成cron表达式来执行定时任务。在“保存”项中添加了自定义定时任务服务插件。代码部分展示了`ExecuteInspectPlanPlugin`类,该类在单据保存后生成或修改调度任务、计划。类中包含了处理属性、添加验证器以及在操作事务后执行的逻辑。此外,还定义了`ExecuteInspectPlanValidator`类用于验证巡检任务的有效性,如检查数据库连接、开始和结束时间等。

在一个数据库巡检项目中,需要设置定时任务,能够按指定的时间重复或单次定期自动巡检,以下为设计的要点:

  1. 参考苍穹标准的定时任务界面进行设计,需要最终主要是生成cron表达式,通过cron表达式执行定时任务。

image.png

image.png

2.在“保存”项添加自定义定时任务服务插件

image.png

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;
    }
}


图标赞 5
5人点赞
还没有人点赞,快来当第一个点赞的人吧!
图标打赏
0人打赏
还没有人打赏,快来当第一个打赏的人吧!