莊周夢(mèng)蝶

          生活、程序、未來
             :: 首頁(yè) ::  ::  :: 聚合  :: 管理

          用osworkflow寫一個(gè)請(qǐng)假例子

          Posted on 2007-03-02 16:07 dennis 閱讀(12308) 評(píng)論(26)  編輯  收藏 所屬分類: java工作流
          update:這個(gè)例子是不當(dāng)?shù)?,更合適的例子請(qǐng)自己上javaeye上搜索個(gè)帖子。源碼俺早就丟了,請(qǐng)不要再發(fā)郵件給我,謝謝。  
              osworkflow擴(kuò)展非常容易,跟我們的應(yīng)用結(jié)合起來使用也很容易。假設(shè)一個(gè)請(qǐng)假流程:?jiǎn)T工請(qǐng)假,需要經(jīng)過部門經(jīng)理和人力資源部經(jīng)理兩人共同審批,只有當(dāng)兩人都許可時(shí)才通過,任一人駁回就失效,也就是一個(gè)and split和and Join流程,并且我們附加一個(gè)要求,當(dāng)發(fā)送請(qǐng)假請(qǐng)求、許可和駁回這幾個(gè)操作時(shí)都將發(fā)送一條消息給相應(yīng)的用戶。
              流程定義文件如下:
          <?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狀態(tài)(流程已經(jīng)啟動(dòng))-->
                                          
          <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狀態(tài)(流程已經(jīng)啟動(dòng))-->
                                          
          <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="部門經(jīng)理批假單">
                      
          <actions>
                          
          <action id="2" name="準(zhǔn)許">
                              
          <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="公司經(jīng)理批假單">
                      
          <actions>
                          
          <action id="4" name="準(zhǔn)許">
                              
          <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>

          請(qǐng)注意,我們?cè)谠S可或者通過的時(shí)候propertySet.setString("action2",......),propertySet.setString("action3",......),然后在join點(diǎn)判斷,如果兩個(gè)都是success,流程結(jié)束;如果一個(gè)是fail,就發(fā)送一個(gè)消息給員工。

          發(fā)送消息的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();
                  }
              }

          }

          得到兩個(gè)參數(shù)groupName和content(消息內(nèi)容),調(diào)用業(yè)務(wù)對(duì)象發(fā)送消息。

          完整代碼下載在《LeaveSystem》

          代碼用到了自己過去寫的一個(gè)MVC框架和持久層,對(duì)此有興趣的參考這三篇文章:
          《設(shè)計(jì)自己的MVC框架》
          《設(shè)計(jì)模式之事務(wù)處理》
          《使用Annotation設(shè)計(jì)持久層》

          如果僅僅是想了解osworkflow的應(yīng)用,建議您跑下流程,讀讀相關(guān)幾個(gè)業(yè)務(wù)類(LeaveServiceImpl.java,SendRemindInfFunction.java,service包下)即可。解壓縮后的文件可以直接導(dǎo)入myeclipse工程,部署在tomcat下,數(shù)據(jù)庫(kù)用的是oracle。跑起來以后可以用3個(gè)用戶登錄,test是雇員組,dennis是部門經(jīng)理組,jordan是公司經(jīng)理,都不需要密碼。寫的比較簡(jiǎn)單,只是實(shí)驗(yàn)性質(zhì),見諒。

          我認(rèn)為使用osworkflow,只要了解了它的表結(jié)構(gòu)和主要原理,根據(jù)你的業(yè)務(wù)需要結(jié)合幾張主要表(os_wfentry,os_currentstep,os_historystep等)合理設(shè)計(jì)數(shù)據(jù)庫(kù)和業(yè)務(wù)流程,可以省去過去為每個(gè)業(yè)務(wù)流程對(duì)象創(chuàng)建的一大堆flag(標(biāo)志,目前的流程狀態(tài))的累贅,充分利用工作流的威力。比如為部門經(jīng)理和人力資源部經(jīng)理顯示不同的需要審批的假單列表,只要結(jié)合os_historystep表進(jìn)行聯(lián)合查詢,部門經(jīng)理的應(yīng)該是執(zhí)行了未執(zhí)行acion2,step在3的;而人力資源部經(jīng)理得到的同樣是step在3,action未執(zhí)行3的。

          手癢癢,很想把去年為一家公司寫的績(jī)效考核系統(tǒng)改寫一下,當(dāng)時(shí)設(shè)計(jì)的一個(gè)contract對(duì)象擁有7,8個(gè)flag來標(biāo)志合約狀態(tài)(直接上級(jí)審核,人力資源評(píng)價(jià),KPI評(píng)價(jià)等),搞的非?;靵y,而且流程寫死在代碼里,如果以后要改變考核流程,只有重新寫過一套。不過那家公司是國(guó)有企業(yè),每年的固定的預(yù)算費(fèi)用一定要花掉,反正大家一起賺國(guó)家的錢嘛。


          評(píng)論

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子  回復(fù)  更多評(píng)論   

          2007-03-02 17:38 by BeanSoft
          氣氛有點(diǎn)冷清...

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子[未登錄]  回復(fù)  更多評(píng)論   

          2007-03-02 18:11 by test
          沒有運(yùn)行代碼下載???

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子(提供代碼下載)  回復(fù)  更多評(píng)論   

          2007-03-02 18:54 by dennis
          @test
          放上去了,因?yàn)橛玫竭^去自己寫一些基礎(chǔ)框架,怕誤導(dǎo)人,一開始沒敢放上去,下載地址
          http://www.aygfsteel.com/Files/killme2008/LeaveSystem.rar

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子(提供代碼下載)  回復(fù)  更多評(píng)論   

          2007-03-05 14:21 by kk
          請(qǐng)問下您的這個(gè)例子如何配置運(yùn)行,我部署在tomcat下好象運(yùn)行不了。
          我的郵箱BreatheTakingBeauty@hotmail.com

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子(提供代碼下載)  回復(fù)  更多評(píng)論   

          2007-03-05 21:23 by hello
          最近公司 在 osworkflow & jbpm 間做 選擇,
          我研究 osworkflow ,看到 你 的 例子 ,不錯(cuò) ,贊一個(gè) ,
          可代碼 不能 下 嗎??

          可否發(fā) 給 本人,謝謝

          truthyd@126.com

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子(提供代碼下載)  回復(fù)  更多評(píng)論   

          2007-03-06 08:46 by dennis
          @hello
          我對(duì)osworkflow也在學(xué)習(xí)階段,這幾天看了下代碼,這個(gè)例子還是寫的太差,特別是沒有用到osworkflow的狀態(tài)查詢功能,而是直接結(jié)合表來查詢數(shù)據(jù)庫(kù),導(dǎo)致代碼寫死了。沒什么參考價(jià)值,準(zhǔn)備改改

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子(提供代碼下載)  回復(fù)  更多評(píng)論   

          2007-03-06 10:11 by allan
          你好,你的那個(gè)例子似乎不能下,能不能發(fā)給我一份?
          地址:allan0410@qq.com
          也交個(gè)朋友,我現(xiàn)在急需一個(gè)像你的這個(gè)例子,對(duì)于初學(xué)osworkflow的幫助很大。。。

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子(提供代碼下載)  回復(fù)  更多評(píng)論   

          2007-03-06 10:15 by allan
          在線等待。。。!~

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子  回復(fù)  更多評(píng)論   

          2007-03-06 11:26 by dennis
          @allan
          又放上去了,例子寫的確實(shí)不好,有空修改下,最好的方式還是調(diào)用osworkflow的查詢API來進(jìn)行狀態(tài)查詢,而非我現(xiàn)在做的直接查詢數(shù)據(jù)庫(kù)。倒有點(diǎn)后悔放上去了,希望沒誤導(dǎo)人

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子(提供代碼下載)  回復(fù)  更多評(píng)論   

          2007-03-06 15:11 by allan
          怎么用eclipse3.2打開包錯(cuò)???。。。
          似乎沒包

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子(提供代碼下載)  回復(fù)  更多評(píng)論   

          2007-03-06 15:17 by allan
          能不能告訴我你那個(gè)工程要導(dǎo)入那些包??

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子  回復(fù)  更多評(píng)論   

          2007-03-06 16:24 by allan
          跪求myutil.jar包,樓主能不能將源碼發(fā)給我。。。
          感激泣零

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子  回復(fù)  更多評(píng)論   

          2007-03-06 16:29 by dennis
          @allan
          myutll.jar在WEB-INF/lib下,其他的就是需要osworflow的支持包,請(qǐng)自行下載

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子  回復(fù)  更多評(píng)論   

          2007-03-07 13:21 by dennis
          那里需要重寫ConnectionManager,你所需要做的只是配置數(shù)據(jù)源而已,我不是在db_setup目錄下方了一個(gè)leave.xml,修改下里面的數(shù)據(jù)庫(kù)名配置,拷貝到tomcat安裝目錄下的\conf\Catalina\localhost就可以了

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子  回復(fù)  更多評(píng)論   

          2007-03-07 14:19 by allan
          昏,問題解決了。。。
          原來是要拷到tomcat-common-lib下面
          這種連接方式太依賴服務(wù)器了。。。

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子  回復(fù)  更多評(píng)論   

          2007-03-07 15:16 by dennis
          @allan
          哎,本來就是個(gè)例子,你指望他干什么呢?我本來就不想把代碼放上來的。請(qǐng)別再刷評(píng)論了,謝謝

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子  回復(fù)  更多評(píng)論   

          2007-03-14 10:30 by zyg
          hi,你那個(gè)例子連接失效,能不能發(fā)郵件給我一個(gè),萬分感謝

          我的郵箱地址 yg_zhangyg@tecamo.com

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子  回復(fù)  更多評(píng)論   

          2007-03-22 15:01 by hiya
          代碼下不了。是否已經(jīng)刪了。
          我的郵箱:chf@tsinghua.org.cn
          有BaseJDBCProvider.java文件嗎,發(fā)一個(gè),謝謝先。

          我連不上數(shù)據(jù)源
          Could not look up DataSource錯(cuò)。

          請(qǐng)教?。。?!
          急?。。。?/div>

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子  回復(fù)  更多評(píng)論   

          2007-03-27 10:34 by aa
          代碼下不了。是否已經(jīng)刪了。
          我的郵箱:zzzyqqq@163.com
          有BaseJDBCProvider.java文件嗎,發(fā)一個(gè),謝謝先。

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子[未登錄]  回復(fù)  更多評(píng)論   

          2007-04-05 23:45 by Jeff
          代碼下不了? 我的郵箱是wji@ryerson.ca 請(qǐng)發(fā)一份好嗎?

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子  回復(fù)  更多評(píng)論   

          2007-04-13 15:40 by yangrong
          能把你的例子給我發(fā)一份嗎?
          yangrongqiang@163.com,謝謝。

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子  回復(fù)  更多評(píng)論   

          2007-04-15 11:04 by dennis
          @yangrong
          sorry,這個(gè)代碼我已經(jīng)刪除了,我覺的寫的很爛,那時(shí)對(duì)osworkflow的理解還停留在初步了解,代碼不能見人的。請(qǐng)搜索CSDN java版上一個(gè)帖子,我記的有一個(gè)別人寫的例子非常不錯(cuò)。

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子  回復(fù)  更多評(píng)論   

          2007-04-20 16:17 by G_G
          房主不厚道
          :(

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子  回復(fù)  更多評(píng)論   

          2007-06-12 17:17 by yuzhongren
          那位有原碼的能不能發(fā)給我一份阿,謝謝了zfjwzh@163.com

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子  回復(fù)  更多評(píng)論   

          2007-06-13 13:54 by zhangying
          你好
          能給我發(fā)一份嗎>我的郵箱zhangy@sict.ac.cn
          非常感謝

          # re: 用osworkflow寫一個(gè)請(qǐng)假例子  回復(fù)  更多評(píng)論   

          2007-07-03 14:13 by e
          你好 。
          給我也發(fā)一份。
          guzhuopiao@hotmail.com
          主站蜘蛛池模板: 华宁县| 河津市| 保山市| 柯坪县| 车致| 高平市| 乌审旗| 延川县| 新和县| 揭阳市| 永城市| 昔阳县| 雷州市| 金溪县| 保德县| 剑川县| 青田县| 孝义市| 汝阳县| 湟中县| 双鸭山市| 沙河市| 永城市| 班玛县| 大石桥市| 冷水江市| 韩城市| 沙河市| 丹东市| 北安市| 嘉禾县| 大冶市| 五指山市| 浦县| 色达县| 海盐县| 金平| 富源县| 黄石市| 松阳县| 德令哈市|