該項(xiàng)目包含的通用模塊代碼等我有時(shí)間一并剝離貢獻(xiàn)出來(基于WebSocket的通知引擎,工作流整合模塊,自定義表單(詳見這里),基于RBAC權(quán)限設(shè)計(jì)),最近太忙了,Web項(xiàng)目有一段時(shí)間沒碰,有點(diǎn)生疏的感覺,主要在忙GQT項(xiàng)目,一套基于桌面開發(fā)的框架,詳見這里,寫代碼寫的有點(diǎn)手酸的感覺。
基于Web的含工作流的項(xiàng)目看起來并不如想象的那么簡單,主要需求:
- 靈活定制工作流,并跟蹤流程進(jìn)度;
- 每個(gè)Order含有歷史軌跡記錄,可在歷史中查看;
- 工作流的Action靈活,認(rèn)領(lǐng)任務(wù)不一定非要先提取表單,因?yàn)楹芏喙?jié)點(diǎn)都只有幾個(gè)動作,直接按鈕操作即可;
- 待辦事宜列表在不刷新頁面情況下也能變動;
項(xiàng)目要求:
- 操作簡單高效;
- 權(quán)限細(xì)節(jié)到按鈕級別;
- 并發(fā)數(shù)少,不超過3000個(gè)在線用戶;
主要可能使用到技術(shù):
- 工作流引擎,我這里選用Activiti5,很靈活好用;
- 權(quán)限使用Spring Security,基于標(biāo)簽式管理權(quán)限很方便;
- 通知引擎使用WebSocket,基于Flash實(shí)時(shí)通信,基于socket.io;
- 權(quán)限粒度基于經(jīng)典的RBAC;
- 總體框架Spring MVC+Mybatis;
實(shí)現(xiàn)的WebSocket的總體思路:
- WebSocket Server獨(dú)立于Web項(xiàng)目,Web Server與WebSocket Server之間的局域網(wǎng)通信基于簡單的Socket通信,這樣這個(gè)組件可以完全解耦和通用;
- 當(dāng)Web項(xiàng)目要Push消息到Client時(shí),通過Web Server的Socket Client向WebSocket Server的Socker Server發(fā)送消息,然后WebSocket Server收到消息后解碼,廣播到所有瀏覽器;
我們實(shí)現(xiàn)的事件通知非常簡單,設(shè)定全局變量并讓瀏覽器偵聽:
var G_WebSocket=false;
var EVENT_ORDER_CHANGE_STATUS = "orderChange";
var EVENT_ORDER_CHANGE_AMOUNT = "amountChange";
var EVENT_ORDER_CHANGE_REFUND = "refundChange";
WebSocket.init = function(callbackFunc){
socket = io.connect(connUrl, connOptions);
socket.on('connect', function() {
G_WebSocket=true;
callbackFunc("connect",null);
});
socket.on('disconnect', function() {
G_WebSocket=false;
callbackFunc("disconnect",null);
});
socket.on('clientQuit', function(obj){
G_WebSocket=false;
callbackFunc("clientQuit",obj);
});
socket.on('broadcast', function(obj) {
callbackFunc("broadcast",obj);
});
};
在需要偵聽WebSocket接受Web Server推送消息的地方加上一個(gè)函數(shù)即可:
WebSocket.init(function(command,jsonObj){
if(command=="broadcast"){
if(jsonObj.e == EVENT_ORDER_CHANGE_STATUS){
//TODO:write your code here
}else if(jsonObj.e == EVENT_ORDER_CHANGE_AMOUNT){
//TODO:write your code here
}else if(jsonObj.e == EVENT_ORDER_CHANGE_REFUND){
//TODO:write your code here
}
}
});
這樣的結(jié)構(gòu)要擴(kuò)展推送服務(wù)很簡單,比如按頻道推送等,都可以很容易的擴(kuò)展。
再看看看工作流,我們實(shí)現(xiàn)了activiti通用的申請?zhí)峤蝗蝿?wù)流程和自定義表單功能,提取跟蹤流程圖功能等,這樣你要設(shè)計(jì)一個(gè)新流程也變得非常簡單,只需要在eclipse里劃上工作流圖,在后臺發(fā)布,然后通過SpringMVC的RestAPI啟動實(shí)例流程,申領(lǐng)完成任務(wù)等,如下圖:

流程走到了分支的兩個(gè)節(jié)點(diǎn)上,這樣對后續(xù)新增的工作流提供了極大的遍歷。
最后說說Spring Security,基于RBAC的權(quán)限體系搭建好后(可以用在任何管理系統(tǒng)中),要在頁面中訪問一個(gè)資源,首先判斷一下是否有權(quán)限,如下HTML:
<sec:authorize ifAllGranted="r_pd">
<a href="#">resource access here</a>
</sec:authorize>
<sec:authorize url="/XXX/XXX/XXX.html">
<a href="XXX/XXX/XXX.html'">
<span>XXX功能</span>
</a>
</sec:authorize>
前臺由于項(xiàng)目比較小,沒有用到j(luò)s的MVC框架,如backbone等,這里就不再記錄了。