php開發(fā)業(yè)務(wù)工作流的設(shè)計(jì)小結(jié)

業(yè)務(wù)部門希望現(xiàn)有業(yè)務(wù)系統(tǒng)可以改造成類似OA那樣的流程定制化罗售,當(dāng)時(shí)對(duì)系統(tǒng)的代碼邏輯已有一定了解, 存在下面的一些問題:

  • 系統(tǒng)有兩張與工作流相關(guān)的表托慨,卻并沒有實(shí)現(xiàn)一個(gè)流程引擎來統(tǒng)管流程的走向扫皱,代碼內(nèi)直接粗暴的用id值判斷流程埠胖,流程節(jié)點(diǎn)也是直接手寫sql寫進(jìn)數(shù)據(jù)庫.
  • 流程相關(guān)的邏輯凌亂间聊,代碼冗余很多
  • 耦合度很高族购,代碼幾乎都是一次性的,無法被他處調(diào)用
  • 流程邏輯與業(yè)務(wù)邏輯混在一起, 新寫一個(gè)業(yè)務(wù)需求時(shí)往往要花一定精力是書寫流程相關(guān)的邏輯.

針對(duì)現(xiàn)實(shí)情況陵珍,大概有了如下目標(biāo)

  • 流程要可配置寝杖,每個(gè)流程節(jié)點(diǎn)有其固定的key來標(biāo)識(shí)它,包括每個(gè)節(jié)點(diǎn)的處理結(jié)果
  • 實(shí)現(xiàn)一個(gè)流程引擎來統(tǒng)一管理流程
  • 每個(gè)節(jié)點(diǎn)有與之對(duì)應(yīng)的處理類
  • 因?yàn)椴糠止?jié)點(diǎn)的跳轉(zhuǎn)并無特殊邏輯互纯,應(yīng)該有一個(gè)默認(rèn)的節(jié)點(diǎn)處理類瑟幕,它只有保存數(shù)據(jù)和提交流程結(jié)果的邏輯
  • 在流程引擎處對(duì)每個(gè)節(jié)點(diǎn)的處理過程預(yù)埋幾個(gè)鉤子,這樣要另外加入三方邏輯時(shí)就不必改動(dòng)現(xiàn)有的文件

前端可視化實(shí)現(xiàn)

百度了幾次留潦,最后選定了jsPlumb這款插件收苏,結(jié)合bootstrap、artTemplate最終實(shí)現(xiàn)了如下流程可視化效果:


img1

img2

img3

提交的數(shù)據(jù)格式如下:

{
    "workflow_group":"normal",
    "conf":{
        "node_1":{
            "name":"節(jié)點(diǎn)一","key":"node_1","workflow_group":"normal",
            "status":{
                "pass":{"key":"pass","name":"通過","apply_step":"2","next_workflow_key":"node_2"},
                "visit":{"key":"visit","name":"考察","apply_step":"2","next_workflow_key":"node_3"}
            },
            "style":{"left":"407px","top":"354px"}
        },
        "node_2":{
            "name":"節(jié)點(diǎn)二","key":"node_2","workflow_group":"normal",
            "status":{
                "pass":{"key":"pass","name":"通過","apply_step":"3","next_workflow_key":"node_4"}
            },
            "style":{"left":"609px","top":"356px"}
        },
        "node_3":{
            "name":"節(jié)點(diǎn)三","key":"node_3","workflow_group":"normal",
            "status":{
                "back":{"key":"back","name":"退回","apply_step":"99","next_workflow_key":"node_1"},
                "pass":{"key":"pass","name":"通過","apply_step":"","next_workflow_key":"node_2"}
            },
            "style":{"left":"513px","top":"501px"}
        },
        "node_4":{
            "name":"節(jié)點(diǎn)四","key":"node_4","workflow_group":"normal",
            "status":{
                "back":{"key":"back","name":"退回","apply_step":"2","next_workflow_key":"node_3"},
                "pass":{"key":"pass","name":"通過","apply_step":"4","next_workflow_key":"apply_end"}
            },
            "style":{"left":"816px","top":"359px"}
        },
        "apply_end":{
            "name":"業(yè)務(wù)結(jié)束","key":"apply_end","workflow_group":"normal",
            "status":{},
            "style":{"left":"781px","top":"551px"}
        }
    }
}

數(shù)據(jù)表部分

三張流程相關(guān)的表愤兵,一張定義流程組,一張定義流程組的節(jié)點(diǎn),一張定義節(jié)點(diǎn)可選的結(jié)果

CREATE TABLE `workflow_group` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '0:監(jiān)聽流程組',
  `group_name` varchar(20) NOT NULL COMMENT '流程組名',
  `group_key` varchar(20) NOT NULL COMMENT '流程組標(biāo)識(shí)',
  `enable` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否可用',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='流程組表';

CREATE TABLE `workflow_node` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `workflow_group_id` int(11) unsigned NOT NULL COMMENT '流程組ID,0:監(jiān)聽流程組',
  `node_name` varchar(20) NOT NULL COMMENT '節(jié)點(diǎn)名稱',
  `node_key` varchar(20) NOT NULL COMMENT '流程節(jié)點(diǎn)標(biāo)識(shí)',
  `is_deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否被刪除',
  `style` varchar(255) DEFAULT NULL COMMENT '節(jié)點(diǎn)樣式',
  PRIMARY KEY (`id`),
  UNIQUE KEY `workflow_group_id` (`workflow_group_id`,`node_key`),
  CONSTRAINT `workflow_node_ibfk_1` FOREIGN KEY (`workflow_group_id`) REFERENCES `workflow_group` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='流程節(jié)點(diǎn)表';

CREATE TABLE `workflow_result` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `workflow_node_id` int(11) unsigned NOT NULL COMMENT '所屬工作流節(jié)點(diǎn)ID',
  `result_name` varchar(20) NOT NULL COMMENT '結(jié)論名稱',
  `result_key` varchar(20) NOT NULL COMMENT '結(jié)論標(biāo)識(shí)',
  `is_deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否被刪除',
  `next_node_id` int(11) DEFAULT NULL COMMENT '下一個(gè)流程',
  `next_node_key` varchar(20) NOT NULL DEFAULT '' COMMENT '下一個(gè)流程標(biāo)識(shí)'
  PRIMARY KEY (`id`),
  UNIQUE KEY `workflow_id` (`workflow_node_id`,`result_key`),
  CONSTRAINT `workflow_result_ibfk_1` FOREIGN KEY (`workflow_node_id`) REFERENCES `workflow_node` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='流程節(jié)點(diǎn)結(jié)論表';

流程引擎部分

定義了4個(gè)核心文件如下:

  • Workflow.class.php final類
    核心方法如下:
public function getConf($workflow_group){}  //獲取配置
public function setConf($conf,$workflow_group){} //設(shè)置配置
public function getNodeResults($workflow_key,$workflow_group){} //獲取節(jié)點(diǎn)結(jié)果集
public function getListClass($workflow_key, $uid){}//獲取節(jié)點(diǎn)列表處理類
public function getCommitClass($id, $workflow_key, $uid){}//獲取節(jié)點(diǎn)提交處理類
  • WorkflowCommit.class.php abstract類
    每個(gè)節(jié)點(diǎn)處理類都繼承于這個(gè)抽象類排吴,要實(shí)現(xiàn)如下兩個(gè)抽象方法:
// 提交處理
abstract protected function _commit($resultKey, array $data);
// 頁面輸出顯示
abstract protected function _output($id);
  • WorkflowHook.class.php abstract類
    每個(gè)節(jié)點(diǎn)的鉤子文件都繼承于這個(gè)類

  • WorkflowList.class.php abstract類
    列表類秆乳,主要有以下方法:

public function getTpl(){} // 獲取列表模板
public function getMod(){} // 獲取列表模型
public function listFilter(array &$list){} // 列表數(shù)據(jù)過濾
public function setVars(){} // 設(shè)置模板變量

可以定義一個(gè)空類繼承它,作為默認(rèn)列表類钻哩,特殊節(jié)點(diǎn)則定義節(jié)點(diǎn)列表類繼承它覆蓋相關(guān)方法(基本上只用默認(rèn)類就可以了)

寫的比較粗略, 不附帶具體代碼. 下面是最終流程配置的一個(gè)截圖:

img4
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末屹堰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子街氢,更是在濱河造成了極大的恐慌扯键,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件珊肃,死亡現(xiàn)場離奇詭異荣刑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)伦乔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門厉亏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人烈和,你說我怎么就攤上這事爱只。” “怎么了招刹?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵恬试,是天一觀的道長。 經(jīng)常有香客問我疯暑,道長训柴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任缰儿,我火速辦了婚禮畦粮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己宣赔,他們只是感情好预麸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著儒将,像睡著了一般吏祸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上钩蚊,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天贡翘,我揣著相機(jī)與錄音,去河邊找鬼砰逻。 笑死鸣驱,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蝠咆。 我是一名探鬼主播踊东,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼刚操!你這毒婦竟也來了闸翅?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤菊霜,失蹤者是張志新(化名)和其女友劉穎坚冀,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鉴逞,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡记某,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了构捡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辙纬。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖叭喜,靈堂內(nèi)的尸體忽然破棺而出贺拣,到底是詐尸還是另有隱情,我是刑警寧澤捂蕴,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布譬涡,位于F島的核電站,受9級(jí)特大地震影響啥辨,放射性物質(zhì)發(fā)生泄漏涡匀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一溉知、第九天 我趴在偏房一處隱蔽的房頂上張望陨瘩。 院中可真熱鬧腕够,春花似錦、人聲如沸舌劳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽甚淡。三九已至大诸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間贯卦,已是汗流浹背资柔。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留撵割,地道東北人贿堰。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像啡彬,于是被迫代替她去往敵國和親官边。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理外遇,服務(wù)發(fā)現(xiàn),斷路器契吉,智...
    卡卡羅2017閱讀 134,664評(píng)論 18 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,178評(píng)論 25 707
  • 昨天跳仿,妻子參加親戚家娶媳婦的婚宴回來,大發(fā)感慨捐晶,說沒有想到菲语,親戚家初中畢業(yè)的兒子竟然娶了一個(gè)名牌大學(xué)畢業(yè)的美女,而...
    醫(yī)涂漫閱讀 501評(píng)論 1 4
  • 觀晚霞·感 蒼穹一嘯夕霞邊惑灵, 似幻如夢(mèng)癡笑間山上。 蝠飛燕橫長空破, 浪跡四海不作仙英支。 8.1 體育場 天氣不算好佩憾,...
    清風(fēng)隱月閱讀 134評(píng)論 0 0
  • ## 測試
    雨前閱讀 72評(píng)論 0 0