在任务管理流程中,流程的发起是通过模版而进行的,此模板是对拟文的一种持久化,可以重复使用它来发起工作任务管理流程。由于有了模版的存在流程的发起便有了两种发起方式:一种是手动发起流程,另一种是自动发起流程。本文所讲内容涉及的是自动发起流程。
模版的定制过程首先指定其为手动还是自动发起流程,而后指定其发起周期,明确该任务的计划完成时间以及提醒时间。其中模版的发起周期有五种:周度、月度、季度、年度和定时。提醒时间指在计划完成时间之前的天数,在提醒时间的当天发起该模版指定的流程,同时对任务的接收人发送邮件加以说明。
自动执行程序每天凌晨零点开始执行,检查所有模版,根据计划完成时间(日期)和提醒时间(天数)来计算自动执行程序运行的当天是否为提醒时间和计划完成时间指定的发起模版流程的日期,如果是则发起流程发送说明性邮件。
在模版的周期下指定相应类别中的具体一天,自动执行程序即会在每个周期的这一天发起此模板对应的流程。其中周度指周一到周日,月度指1号到31号,季度指第一季度到第四季度(一季度是1到3月中的一天,二季度是4到6月中的一天…),年度指1月1日到12月31,定时指任意一个具体时间如2012-5-31。
对比上述五类周期,可以分为两种,一种是周度和月度,没有指定出具体计划完成时间的日期而是指定周几或几号完成,需要自己手工计算,剩下的三种则指定了。前四种可以说是真正的周期,而定时则是一个具体时间,即仅会执行一次。前四种的计划完成时间则涉及到是处于当前周期内,还是下一个周期中,以此加上提醒时间来计算提醒日期,决定自动程序运行当天是否需要发起此模版。针对此描述示意代码如下所示:
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Iterator; import java.util.List; public void doTask () throws VWException { Date currentDate = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); try { currentDate = sdf.parse(sdf.format(currentDate)); } catch (ParseException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } Calendar calendar = Calendar.getInstance(); calendar.setTime(currentDate); System.out.println("当前时间:" + calendar.get(Calendar.YEAR) + " 年 " + (calendar.get(Calendar.MONTH) + 1) + " 月 " + calendar.get(Calendar.DAY_OF_MONTH) + " 日星期 " + ((calendar.get(Calendar.DAY_OF_WEEK) == 1) ? 7 : (calendar.get(Calendar.DAY_OF_WEEK) - 1))); List<TaskSupervision> taskSupervisionList = taskSupervisionBusinessService.getAll(); if(taskSupervisionList != null){ Iterator<TaskSupervision> iterator = taskSupervisionList.iterator(); while(iterator.hasNext()){ calendar.setTime(currentDate); TaskSupervision next = iterator.next(); String period = next.getPeriod(); System.out.println("周期 : " + period); if("周度".equalsIgnoreCase(period)){ //今天是一周中的第几天 int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); String planCompleteDate = next.getWeekPlanCompleteDate(); int dividing = 0; if("周一".equals(planCompleteDate)){ //周一是一周中的第二天 dividing = 2; }else if("周二".equals(planCompleteDate)){ dividing = 3; }else if("周三".equals(planCompleteDate)){ dividing = 4; }else if("周四".equals(planCompleteDate)){ dividing = 5; }else if("周五".equals(planCompleteDate)){ dividing = 6; }else if("周六".equals(planCompleteDate)){ dividing = 7; }else if("周日".equals(planCompleteDate)){ //周日是一周中的第一天 dividing = 1; } //如果完成日期的周数在今天所处周数之后,则本周为其计划完成日期,如果在其周数之前,则下周为其完成日期,依次计算器提醒时间 int interval = 0; if(dividing >= dayOfWeek){ interval = dividing - dayOfWeek; //计划完成日期 calendar.add(Calendar.DATE, interval); }else{ interval = dayOfWeek - dividing; //计划完成日期 calendar.add(Calendar.DATE, 7-interval); } //获取提醒天数,计算提醒日期 int reminderTime = next.getReminderTime(); calendar.add(Calendar.DATE, -reminderTime); int dayOfWeekToPlan = calendar.get(Calendar.DAY_OF_WEEK); //如果今日为提醒时间,则邮件提醒 try { Date reminderDate = sdf.parse(sdf.format(calendar.getTime())); if(reminderDate.getTime() == currentDate.getTime()){ } } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else if("月度".equalsIgnoreCase(period)) { //当天日 int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH); //计划完成日期的日 String planCompleteDate = next.getMonthPlanCompleteDate(); int intPlanComDay = Integer.parseInt(planCompleteDate); int interval = 0; if(intPlanComDay >= dayOfMonth){ interval = intPlanComDay - dayOfMonth; //计划完成日期 calendar.add(Calendar.DATE, interval); }else{ interval = dayOfMonth - intPlanComDay; //计划完成日期 calendar.add(Calendar.MONTH, 1); calendar.add(Calendar.DATE, -interval); } //获取提醒天数,计算提醒日期 int reminderTime = next.getReminderTime(); calendar.add(Calendar.DATE, -reminderTime); //如果今日为提醒时间,则发起流程,并邮件提醒 try { Date reminderDate = sdf.parse(sdf.format(calendar.getTime())); if(reminderDate.getTime() == currentDate.getTime()){ } } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else if("季度".equalsIgnoreCase(period)) { //检测是否需要发送邮件 try { //提醒天数 int reminderTime = next.getReminderTime(); //第一季度 String planCompleteDate = next.getFirstQuarterPlanCompleteDate(); Date reminderDate = null; //获取提醒时间 Calendar calendarMonth = Calendar.getInstance(); calendarMonth.setTime(sdf.parse(calendar.get(Calendar.YEAR) + "-" + planCompleteDate)); calendarMonth.add(Calendar.DATE, -reminderTime); reminderDate = sdf.parse(sdf.format(calendarMonth.getTime())); //发起流程、邮件提醒 if(currentDate.getTime() == reminderDate.getTime()){ } //第二季度 planCompleteDate = next.getSecondQuarterCompleteDate(); reminderDate = null; //获取提醒时间 calendarMonth = Calendar.getInstance(); calendarMonth.setTime(sdf.parse(calendar.get(Calendar.YEAR) + "-" + planCompleteDate)); calendarMonth.add(Calendar.DATE, -reminderTime); reminderDate = sdf.parse(sdf.format(calendarMonth.getTime())); //发起流程、邮件提醒 if(currentDate.getTime() == reminderDate.getTime()){ } //第三季度 planCompleteDate = next.getThirdQuarterPlanCompleteDate(); reminderDate = null; //获取提醒时间 calendarMonth = Calendar.getInstance(); calendarMonth.setTime(sdf.parse(calendar.get(Calendar.YEAR) + "-" + planCompleteDate)); calendarMonth.add(Calendar.DATE, -reminderTime); reminderDate = sdf.parse(sdf.format(calendarMonth.getTime())); //发起流程、邮件提醒 if(currentDate.getTime() == reminderDate.getTime()){ } //第四季度 planCompleteDate = next.getForthQuarterPlanCompleteDate(); reminderDate = null; //获取提醒时间 calendarMonth = Calendar.getInstance(); calendarMonth.setTime(sdf.parse(calendar.get(Calendar.YEAR) + "-" + planCompleteDate)); calendarMonth.add(Calendar.DATE, -reminderTime); reminderDate = sdf.parse(sdf.format(calendarMonth.getTime())); //发起流程、邮件提醒 if(currentDate.getTime() == reminderDate.getTime()){ } } catch (ParseException e) { e.printStackTrace(); } } else if("年度".equalsIgnoreCase(period)) { //检测是否需要发送邮件 try { String planCompleteDate = next.getYearPlanCompleteDate(); int reminderTime = next.getReminderTime(); Date reminderDate = null; //获取提醒时间 Calendar calendarMonth = Calendar.getInstance(); calendarMonth.setTime(sdf.parse(calendar.get(Calendar.YEAR) + "-" + planCompleteDate)); calendarMonth.add(Calendar.DATE, -reminderTime); reminderDate = sdf.parse(sdf.format(calendarMonth.getTime())); //发起流程、邮件提醒 if(currentDate.getTime() == reminderDate.getTime()){ } } catch (ParseException e) { e.printStackTrace(); } } else if("定时".equalsIgnoreCase(period)){ //Nothing //检测是否需要发送邮件 try { String planCompleteDate = next.getTimePlanCompleteDate(); int reminderTime = next.getReminderTime(); Date reminderDate = null; //获取提醒时间 Calendar calendarMonth = Calendar.getInstance(); calendarMonth.setTime(sdf.parse(planCompleteDate)); calendarMonth.add(Calendar.DATE, -reminderTime); reminderDate = sdf.parse(sdf.format(calendarMonth.getTime())); //发起流程、邮件提醒 if(currentDate.getTime() == reminderDate.getTime()){ } } catch (ParseException e) { e.printStackTrace(); } } } } }
定期执行、周期类别、计划完成时间和提醒时间等关键便构成了这个小需求,而其中的对计划完成时间和提醒时间的业务语意的不明确性便导致了代码的重复性修改,这些问题是可以再明确些,或者是需求或者是算法囊括所有情况,后续继续了解。