最近在學習jBPM和Javascript,所以按照一些相關概念自己寫了下面的200行代碼的“工作流引擎”,工作流管理系統包含了流程定義,引擎,及應用系統三個主要部分,下面的代碼實現了流程的分支合并,目前只支持一種環節上的遷移。拷貝到html,雙擊就可以跑起來。

var workflowDef = {
start:{
fn:"begin", //對應處理方法可以在內部定義,也可以在外部定義
next:["task1","task2"]
},
end:"end",
tasks:[{
id:"task1",
fn:function(){
alert("執行任務一");
},
before:function(){
alert("執行任務一前");
},
after:function(){
alert("執行任務一后");
},
next:["task4","task5"]
},{
id:"task2",
fn:function(){
alert("執行任務二");
},
before:function(){
alert("執行任務二前");
},
after:function(){
alert("執行任務二后");
},
next:["task3"]
},{
id:"task3",
fn:function(){
alert("執行任務三");
},
before:function(){
alert("執行任務三前");
},
after:function(){
alert("執行任務三后");
},
//定義合并的數量
merge: 3,
next:"EOWF"
},{
id:"task4",
fn:function(){
alert("執行任務四");
},
before:function(){
alert("執行任務四前");
},
after:function(){
alert("執行任務四后");
},
next:["task3"]
},{
id:"task5",
fn:function(){
alert("執行任務五");
},
before:function(){
alert("執行任務五前");
},
after:function(){
alert("執行任務五后");
},
next:["task3"]
}]
}
//////////定義引擎////////////
Yi = {};
Yi.Utils = {};
Yi.Utils.execute = function(o){
if(typeof o != 'function')
eval(o)();
else
o();
}
//工作流類
Yi.Workflow = function(workflowDef){
this.def = workflowDef;
this.tasks = this.def.tasks;
}
//public按照環節id查找查找
Yi.Workflow.prototype.findTask = function(taskId){
for(var i=0;i<this.tasks.length;i++){
if(this.tasks[i].id == taskId)
return this.tasks[i];
}
}
//public啟動工作流
Yi.Workflow.prototype.start = function(){
this.currentTasks = [];
Yi.Utils.execute(this.def.start.fn);
for(var i=0;i<this.def.start.next.length;i++){
this.currentTasks[i] = this.findTask(this.def.start.next[i]);
Yi.Utils.execute(this.currentTasks[i].before);
}
}
//private
Yi.Workflow.prototype.findCurrentTaskById = function(taskId){
for(var i=0;i<this.currentTasks.length;i++){
if(this.currentTasks[i].id == taskId)
return this.currentTasks[i];
}
return null;
}
//private
Yi.Workflow.prototype.removeFromCurrentTasks = function(task){
var temp = [];
for(var i=0;i<this.currentTasks.length;i++){
if(!(this.currentTasks[i] == task))
temp.push(this.currentTasks[i]);
}
this.currentTasks = temp;
temp = null;
}
//public觸發當前環節
Yi.Workflow.prototype.signal = function(taskId){
//只處理當前活動環節
var task = this.findCurrentTaskById(taskId);
if(task == null){
alert("工作流未流轉到此環節!");
return;
}
//對于合并的處理
if(task.merge != undefined){
if(task.merge != 0){
alert("工作流流轉條件不充分!");
return;
}else{
Yi.Utils.execute(task.before);
}
}
//觸發當前環節
Yi.Utils.execute(task.fn);
//觸發后動作
Yi.Utils.execute(task.after);
//下一步如果工作流結束
if(task.next === "EOWF"){
Yi.Utils.execute(this.def.end);
delete this.currentTasks;
return;
}
//遍歷下一步環節
this.removeFromCurrentTasks(task);
for(var i=0;i<task.next.length;i++){
var tempTask = this.findTask(task.next[i]);
if(!tempTask.inCurrentTasks)
this.currentTasks.push(tempTask);
if(tempTask.merge != undefined){
tempTask.merge--;
tempTask.inCurrentTasks = true;
}
else
Yi.Utils.execute(tempTask.before);
}
}
//public獲取當前的活動環節
Yi.Workflow.prototype.getCurrentTasks = function(){
return this.currentTasks;
}
//public獲取流程定義
Yi.Workflow.prototype.getDef = function(){
return this.def;
}
////////應用系統///////////////
var wf = new Yi.Workflow(workflowDef);
alert("啟動工作流");
wf.start();
alert("嘗試手工執行任務3,返回工作流沒有流轉到這里");
wf.signal("task3");
alert("分支開始");
alert("手工執行任務1");
wf.signal("task1");
alert("手工執行任務2");
wf.signal("task2");
alert("手工執行任務4");
wf.signal("task4");
alert("手工執行任務5");
wf.signal("task5");
alert("手工執行任務3");
wf.signal("task3");
function begin(){
alert("流程開始,該函數在外部定義");
}
function end(){
alert("流程結束");
}
@2008 楊一. 版權所有. 保留所有權利