用osworkflow写一个请假例子

    xiaoxiao2024-01-09  151

    update:这个例子是不当的,更合适的例子请自己上javaeye上搜索个帖子。源码俺早就丢了,请不要再发邮件给我,谢谢。       osworkflow扩展非常容易,跟我们的应用结合起来使用也很容易。假设一个请假流程:员工请假,需要经过部门经理和人力资源部经理两人共同审批,只有当两人都许可时才通过,任一人驳回就失效,也就是一个and split和and Join流程,并且我们附加一个要求,当发送请假请求、许可和驳回这几个操作时都将发送一条消息给相应的用户。     流程定义文件如下: <? xml version="1.0" encoding="UTF-8"  ?> <! DOCTYPE workflow PUBLIC "-//OpenSymphony Group//DTD OSWorkflow 2.7//EN"  "http://www.opensymphony.com/osworkflow/workflow_2_7.dtd" > < workflow >      < initial-actions >          < action  id ="0"  name ="开始" >              < pre-functions >                  < function  type ="class" >                      < arg  name ="class.name" >                         com.opensymphony.workflow.util.Caller                      </ arg >                  </ function >              </ pre-functions >              < results >                  < unconditional-result  old-status ="Finished"                     status ="Underway"  step ="1"  owner ="${caller}"   />              </ results >          </ action >      </ initial-actions >      < steps >          < step  id ="1"  name ="填假单" >              < external-permissions >                  < permission  name ="permA" >                      < restrict-to >                          < conditions  type ="AND" >                              < condition  type ="class" > <!-- 流程处于Underway状态(流程已经启动) -->                                  < arg  name ="class.name" >                                     com.opensymphony.workflow.util.StatusCondition                                  </ arg >                                  < arg  name ="status" > Underway </ arg >                              </ condition >                              < condition  type ="class" >                                  < arg  name ="class.name" >                                     com.opensymphony.workflow.util.AllowOwnerOnlyCondition                                  </ arg >                              </ condition >                          </ conditions >                      </ restrict-to >                  </ permission >              </ external-permissions >              < actions >                  < action  id ="1"  name ="送出" >                      < restrict-to >                          < conditions  type ="AND" >                              < condition  type ="class" > <!-- 流程处于Underway状态(流程已经启动) -->                                  < arg  name ="class.name" >                                     com.opensymphony.workflow.util.StatusCondition                                  </ arg >                                  < arg  name ="status" > Underway </ arg >                              </ condition >                              < condition  type ="class" >                                  < arg  name ="class.name" >                                     com.opensymphony.workflow.util.AllowOwnerOnlyCondition                                  </ arg >                              </ condition >                          </ conditions >                      </ restrict-to >                      < pre-functions >                          < function  type ="class" >                              < arg  name ="class.name" >                                 com.opensymphony.workflow.util.Caller                              </ arg >                          </ function >                      </ pre-functions >                      < results >                          < unconditional-result  old-status ="Finished"                             split ="1"  status ="Queued" >                              < post-functions >                                  < function  type ="class" >                                      < arg  name ="class.name" >                                         net.rubyeye.leavesys.service.workflow.SendRemindInfFunction                                      </ arg >                                      < arg  name ="groupName" >                                         AND (GROUPNAME='dept_manager' or                                         GROUPNAME='comp_manager')                                      </ arg >                                      < arg  name ="content" >                                         you have leavemsg to                                         check!please check it!                                      </ arg >                                  </ function >                              </ post-functions >                          </ unconditional-result >                      </ results >                  </ action >              </ actions >          </ step >          < step  id ="2"  name ="部门经理批假单" >              < actions >                  < action  id ="2"  name ="准许" >                      < restrict-to >                          < conditions >                              < condition  type ="class" >                                  < arg  name ="class.name" >                                     com.opensymphony.workflow.util.OSUserGroupCondition                                  </ arg >                                  < arg  name ="group" > dept_manager </ arg >                              </ condition >                          </ conditions >                      </ restrict-to >                      < pre-functions >                          < function  type ="class" >                              < arg  name ="class.name" >                                 com.opensymphony.workflow.util.Caller                              </ arg >                          </ function >                          < function  type ="beanshell" >                              < arg  name ="script" >                                 propertySet.setString("action1",                                 "success");                              </ arg >                          </ function >                      </ pre-functions >                      < results >                          < unconditional-result  old-status ="Finished"                             status ="Queued"  join ="1"  owner ="${caller}"   />                      </ results >                  </ action >                  < action  id ="3"  name ="驳回" >                      < restrict-to >                          < conditions >                              < condition  type ="class" >                                  < arg  name ="class.name" >                                     com.opensymphony.workflow.util.OSUserGroupCondition                                  </ arg >                                  < arg  name ="group" > dept_manager </ arg >                              </ condition >                          </ conditions >                      </ restrict-to >                      < pre-functions >                          < function  type ="class" >                              < arg  name ="class.name" >                                 com.opensymphony.workflow.util.Caller                              </ arg >                          </ function >                          < function  type ="beanshell" >                              < arg  name ="script" >                                 propertySet.setString("action1",                                 "fail");                              </ arg >                          </ function >                      </ pre-functions >                      < results >                          < unconditional-result  old-status ="Finished"                             status ="Queued"  join ="2"  owner ="${caller}"   />                      </ results >                  </ action >              </ actions >          </ step >          < step  id ="3"  name ="公司经理批假单" >              < actions >                  < action  id ="4"  name ="准许" >                      < restrict-to >                          < conditions >                              < condition  type ="class" >                                  < arg  name ="class.name" >                                     com.opensymphony.workflow.util.OSUserGroupCondition                                  </ arg >                                  < arg  name ="group" > comp_manager </ arg >                              </ condition >                          </ conditions >                      </ restrict-to >                      < pre-functions >                          < function  type ="class" >                              < arg  name ="class.name" >                                 com.opensymphony.workflow.util.Caller                              </ arg >                          </ function >                          < function  type ="beanshell" >                              < arg  name ="script" >                                 propertySet.setString("action2",                                 "success");                              </ arg >                          </ function >                      </ pre-functions >                      < results >                          < unconditional-result  old-status ="Finished"                             status ="Queued"  join ="1"  owner ="${caller}"   />                      </ results >                  </ action >                  < action  id ="5"  name ="驳回" >                      < restrict-to >                          < conditions >                              < condition  type ="class" >                                  < arg  name ="class.name" >                                     com.opensymphony.workflow.util.OSUserGroupCondition                                  </ arg >                                  < arg  name ="group" > dept_manager </ arg >                              </ condition >                          </ conditions >                      </ restrict-to >                      < pre-functions >                          < function  type ="class" >                              < arg  name ="class.name" >                                 com.opensymphony.workflow.util.Caller                              </ arg >                          </ function >                          < function  type ="beanshell" >                              < arg  name ="script" >                                 propertySet.setString("action2",                                 "fail");                              </ arg >                          </ function >                      </ pre-functions >                      < results >                          < unconditional-result  old-status ="Finished"                             status ="Queued"  join ="2"  owner ="${caller}"   />                      </ results >                  </ action >              </ actions >          </ step >          < step  id ="4"  name ="停止"   />      </ steps >      < splits >          < split  id ="1" >              < unconditional-result  old-status ="Finished"  status ="Queued"                 step ="2"   />              < unconditional-result  old-status ="Finished"  status ="Queued"                 step ="3"   />          </ split >      </ splits >      < joins >          < join  id ="1" >              < conditions  type ="AND" >                  < condition  type ="beanshell" >                      < arg  name ="script" >                          <![CDATA[      "Finished".equals(jn.getStep(2).getStatus()) &&         "Finished".equals(jn.getStep(3).getStatus())&&"success".equals(propertySet.getString("action1"))&&         "success".equals(propertySet.getString("action2"))        ]]>                      </ arg >                  </ condition >              </ conditions >              < unconditional-result  old-status ="Finished"  status ="Queued"                 step ="4" />          </ join >          < join  id ="2" >              < conditions  type ="OR" >                  < condition  type ="beanshell" >                      < arg  name ="script" >                          <![CDATA[      "Finished".equals(jn.getStep(2).getStatus()) &&"fail".equals(propertySet.getString("action1"))        ]]>                      </ arg >                  </ condition >                  < condition  type ="beanshell" >                      < arg  name ="script" >                          <![CDATA[              "Finished".equals(jn.getStep(3).getStatus())&&"fail".equals(propertySet.getString("action2"))        ]]>                      </ arg >                  </ condition >              </ conditions >              < unconditional-result  old-status ="Finished"  step ="4"                 status ="Queued" >                  < post-functions >                      < function  type ="class" >                          < arg  name ="class.name" >                             net.rubyeye.leavesys.service.workflow.SendRemindInfFunction                          </ arg >                          < arg  name ="groupName" >                             AND GROUPNAME='employee'                           </ arg >                          < arg  name ="content" >                             you leveamsg is fail!!!                          </ arg >                      </ function >                  </ post-functions >              </ unconditional-result >          </ join >      </ joins > </ workflow > 请注意,我们在许可或者通过的时候 propertySet.setString("action2",......), propertySet.setString("action3",......) ,然后在join点判断,如果两个都是success,流程结束;如果一个是fail,就发送一个消息给员工。 发送消息的function像这样: package  net.rubyeye.leavesys.service.workflow; import  java.sql.SQLException; import  java.util.Map; import  net.rubyeye.leavesys.domain.RemindInf; import  net.rubyeye.leavesys.service.ManagerFactory; import  com.opensymphony.module.propertyset.PropertySet; import  com.opensymphony.workflow.FunctionProvider; import  com.opensymphony.workflow.WorkflowException; public   class  SendRemindInfFunction  implements  FunctionProvider {      public   void  execute(Map transientVars, Map args, PropertySet ps)              throws  WorkflowException {         String groupName  =  (String) args.get( " groupName " );         String content  =  (String) args.get( " content " );         RemindInf remindInf  =   new  RemindInf();         remindInf.setContent(content);          try  {             ManagerFactory.getRemindService().addRemindInfByGroupName(                     groupName, remindInf);         }  catch  (SQLException e) {             e.printStackTrace();         }  catch  (Exception ex) {             ex.printStackTrace();         }     } }

    文章转自庄周梦蝶  ,原文发布时间5.17

    得到两个参数groupName和content(消息内容),调用业务对象发送消息。 完整代码下载在《LeaveSystem》 代码用到了自己过去写的一个MVC框架和持久层,对此有兴趣的参考这三篇文章:《设计自己的MVC框架》《设计模式之事务处理》《使用Annotation设计持久层》 如果仅仅是想了解osworkflow的应用,建议您跑下流程,读读相关几个业务类(LeaveServiceImpl.java,SendRemindInfFunction.java,service包下)即可。解压缩后的文件可以直接导入myeclipse工程,部署在tomcat下,数据库用的是oracle。跑起来以后可以用3个用户登录,test是雇员组,dennis是部门经理组,jordan是公司经理,都不需要密码。写的比较简单,只是实验性质,见谅。 我认为使用osworkflow,只要了解了它的表结构和主要原理,根据你的业务需要结合几张主要表(os_wfentry,os_currentstep,os_historystep等)合理设计数据库和业务流程,可以省去过去为每个业务流程对象创建的一大堆flag(标志,目前的流程状态)的累赘,充分利用工作流的威力。比如为部门经理和人力资源部经理显示不同的需要审批的假单列表,只要结合os_historystep表进行联合查询,部门经理的应该是执行了未执行acion2,step在3的;而人力资源部经理得到的同样是step在3,action未执行3的。 手痒痒,很想把去年为一家公司写的绩效考核系统改写一下,当时设计的一个contract对象拥有7,8个flag来标志合约状态(直接上级审核,人力资源评价,KPI评价等),搞的非常混乱,而且流程写死在代码里,如果以后要改变考核流程,只有重新写过一套。不过那家公司是国有企业,每年的固定的预算费用一定要花掉,反正大家一起赚国家的钱嘛。

    最新回复(0)