gooflow0.6的流程設計

爲什麼使用gooflow:一、兼容性好javascript

                       二、擴展點不少能夠個性化設計css

                       三、配有api文檔html

                       四、json格式的數據傳輸java

gooflow0.8版node

gooflow2.0版jquery

因爲最近項目須要,急需設計一個流程,考慮到時間問題,和用戶個性化的需求,沒辦法跟如今項目的後臺集成,因此考慮到選擇一款jquery插件,並經過存儲過程來集成如今的業務模塊。ajax

 

直接上圖了:spring

雙擊節點能夠選擇人員json

雙擊鏈接線能夠選擇條件api

使用gooflow版本爲0.4的 網上能夠搜到 另外當前版本有些bug須要本身改。須要提供幫助的能夠加我QQ:512948935

gooflow版本爲0.6

後臺使用的是mvc+spring+NHibernate,主要是保存比較麻煩。

 前臺js

<script type="text/javascript">
    var property = {
        toolBtns: ["start", "end", "task"],
        haveHead: true,
        headBtns: ["save", "undo", "redo", "reload"], //若是haveHead=true,則定義HEAD區的按鈕
        haveTool: true,
        haveGroup: true,
        useOperStack: true
    };
    var remark = {
        cursor: "選擇指針",
        direct: "轉換連線",
        start: "開始結點",
        end: "結束結點",
        task: "任務結點",
        group: "組織劃分框編輯開關"
    };
    var gooFlow, focusId, flow_title, flowID;
    $(function () {
        gooFlow = $.createGooFlow($("#flow"), property);
        flow_title = getUrlParam1("title");
        flowID = getUrlParam("flowID");
        if (flow_title != "") {
            //自適應調整
            gooFlow.reinitSize($(this).width() - 5, $(parent).height() - 25);
            gooFlow.setTitle(flow_title + "·流程繪製");
            parent.$('#div_layout').layout('panel', 'center').panel({
                onResize: function (width, height) {
                    gooFlow.reinitSize(width - 5, height - 30);
                }
            });
        }
        else
            gooFlow.reinitSize($(this).width() - 5, $(this).height() - 5);
        if (flowID == "") flowID = 0;
        gooFlow.setNodeRemarks(remark);
        //新建流程
        gooFlow.onBtnNewClick = function () {
            gooFlow.clearData();
        }
        //保存流程
        gooFlow.onBtnSaveClick = function () {
            var h = gooFlow.$bgDiv.height();
            $("<div class=\"datagrid-mask\"></div>").css({ display: "block", width: "100%", height: h }).appendTo(gooFlow.$bgDiv);
            $("<div class=\"datagrid-mask-msg\"></div>").html("數據正在保存中,請稍候……").appendTo(gooFlow.$bgDiv).css({
                display: "block",
                left: (gooFlow.$bgDiv.width() - 200) / 2,
                top: (h - 45) / 2
            });
            var obj = gooFlow.exportAlter();
            //節點
            var nodeData = "";
            for (var i in obj.nodes) {
                var id = gooFlow.$nodeData[i].ID == null ? 0 : gooFlow.$nodeData[i].ID;
                var userID = gooFlow.$nodeData[i].userID == null ? 0 : gooFlow.$nodeData[i].userID;
                nodeData += '{"ID": ' + id + ''
                                     + ',"FlowID": ' + flowID + ''
                                     + ',"NodeID": "' + i + '"'
                                     + ',"UserID": "' + userID + '"'
                                     + ',"UserName": "' + gooFlow.$nodeData[i].name + '"'
                                     + ',"NodeType":  "' + gooFlow.$nodeData[i].type + '"'
                                     + ',"NodeLeft":  ' + gooFlow.$nodeData[i].left + ''
                                     + ',"NodeTop":  ' + gooFlow.$nodeData[i].top + ''
                                     + ',"NodeWidth":  ' + gooFlow.$nodeData[i].width + ''
                                     + ',"NodeHeight":  ' + gooFlow.$nodeData[i].height + ''
                                     + ',"Marked": false},';
            }
            if (nodeData != "") {
                nodeData = "[" + $.trimend(nodeData, ',') + "]";
            }
            //鏈接線
            var lineData = "";
            for (var i in obj.lines) {
                var id = gooFlow.$lineData[i].ID == null ? 0 : gooFlow.$lineData[i].ID;
                var conditionID = gooFlow.$lineData[i].conditionID == null ? 0 : gooFlow.$lineData[i].conditionID;
                var lineM = gooFlow.$lineData[i].M == null ? 0 : gooFlow.$lineData[i].M;
                lineData += '{"ID": ' + id + ''
                                  + ',"FlowID": ' + flowID + ''
                                     + ',"LineID": "' + i + '"'
                                     + ',"ConditionID": ' + conditionID + ''
                                     + ',"ConditionName": "' + gooFlow.$lineData[i].name + '"'
                                     + ',"LineType":  "' + gooFlow.$lineData[i].type + '"'
                                     + ',"LineFrom":  "' + gooFlow.$lineData[i].from + '"'
                                     + ',"LineTo":  "' + gooFlow.$lineData[i].to + '"'
                                     + ',"LineM":  ' + lineM + ''
                                     + ',"Marked": false},';
            }
            if (lineData != "") {
                lineData = "[" + $.trimend(lineData, ',') + "]";
            }
            //區域
            var areaData = "";
            for (var i in obj.areas) {
                var id = gooFlow.$areaData[i].ID == null ? 0 : gooFlow.$areaData[i].ID;
                areaData += '{"ID": ' + id + ''
                                     + ',"FlowID": ' + flowID + ''
                                     + ',"AreaID": "' + i + '"'
                                     + ',"AreaName":  "' + gooFlow.$areaData[i].name + '"'
                                     + ',"AreaLeft":  ' + gooFlow.$areaData[i].left + ''
                                     + ',"AreaTop":  ' + gooFlow.$areaData[i].top + ''
                                     + ',"AreaWidth":  ' + gooFlow.$areaData[i].width + ''
                                     + ',"AreaHeight":  ' + gooFlow.$areaData[i].height + ''
                                     + ',"AreaColor":  "' + gooFlow.$areaData[i].color + '"'
                                     + ',"Marked": false},';
            }
            if (areaData != "") {
                areaData = "[" + $.trimend(areaData, ',') + "]";
            }
            if (nodeData == "" && lineData == "" && areaData == "") {
                $('.datagrid-mask-msg').remove();
                $('.datagrid-mask').remove();
                return;
            }
            $.ajax({
                type: "post",
                url: "/HR/BacthSave",
                data: { node: nodeData, line: lineData, area: areaData },
                success: function (data) {
                    if (data.status == 1) {
                        jqAlert('保存成功.', 'info', "reload");
                    }
                    else
                        jqAlert('保存失敗:' + data, 'error')
                    $('.datagrid-mask-msg').remove();
                    $('.datagrid-mask').remove();
                }
            });
        }
        //刷新
        gooFlow.onFreshClick = function () {
            location.reload();
        }
        //單元節點雙擊事件
        gooFlow.$workArea.delegate(".ico + td", "dblclick", { inthis: gooFlow }, function (e) {
            var newId = $(this).parents(".GooFlow_item").attr("id");
            var $frame = $("#frame_choose_aud");
            if ($frame.attr("src") == undefined) {
                focusId = newId;
                $frame.attr("src", "/HR/BaseFlowChooseEmp");
            }
            else {
                if (focusId != newId) {
                    focusId = newId;
                    window.frames["choose_aud"].initData();
                }
            }
            $("#div_win_choose_aud").window('open');
        });
        //單元鏈接線雙擊事件
        var tmpClk = "PolyLine";
        if (GooFlow.prototype.useSVG != "")
            tmpClk = "g";
        $(gooFlow.$draw).delegate(tmpClk, "dblclick", { inthis: gooFlow }, function (e) {
            if (GooFlow.prototype.useSVG != "") {
                var $frame = $("#frame_choose_con");
                if ($frame.attr("src") == undefined) {
                    focusId = this.id;
                    $frame.attr("src", "/HR/BaseFlowCondition?typeID=" + getUrlParam("typeID"));
                }
                else {
                    if (focusId != this.id) {
                        focusId = this.id;
                        window.frames["choose_con"].unselect();
                    }
                }
                $("#div_win_choose_con").window('open');
            }
        });
        //操做單元刪除事件
        gooFlow.onItemDel = function (id, type) {
            var delItem = gooFlow.getItemInfo(id, type);
            if (delItem.ID != null) {
                uiConfirm("肯定要刪除該單元嗎.", function () {
                    $.post("/HR/DeleteFlowItem", { "id": id, "type": type }, function (data) {
                        if (data.status == 1) {
                            delItem.ID = null;
                            if (type == "node")
                                gooFlow.delNode(id);
                            else if (type == "line")
                                gooFlow.delLine(id);
                            else if (type == "area")
                                gooFlow.delArea(id);
                            return true;
                        }
                        else
                            jqAlert('刪除失敗:' + data, 'error')
                    });
                });
            }
            else
                return true
        }
        //初始化人員選擇窗體
        showMyWindow($("#div_win_choose_aud"), '選擇人員信息', 'icon-edit', '', 900, 450, true);
        //初始化人員選擇窗體
        showMyWindow($("#div_win_choose_con"), '選擇條件信息', 'icon-edit', '', 900, 450, true);
        //加載數據
        var h = gooFlow.$bgDiv.height();
        $("<div class=\"datagrid-mask\"></div>").css({ display: "block", width: "100%", height: h }).appendTo(gooFlow.$bgDiv);
        $("<div class=\"datagrid-mask-msg\"></div>").html("圖形正在加載中,請稍候……").appendTo(gooFlow.$bgDiv).css({
            display: "block",
            left: (gooFlow.$bgDiv.width() - 200) / 2,
            top: (h - 45) / 2
        });
        var para = { "type": "get", "url": "/HR/LoadWorkArea?flowID=" + flowID, "success": onLoadSuccess, "error": onLoadError };
        gooFlow.loadDataAjax(para);
    });
    function onLoadSuccess(msg) {
        $('.datagrid-mask-msg').remove();
        $('.datagrid-mask').remove();
    }
    function onLoadError(status, errorThrown) {
        $('.datagrid-mask-msg').remove();
        $('.datagrid-mask').remove();
    }
    function backAudChoose(row) {
        gooFlow.setName(focusId, row.user_truename + "(" + row.user_no + ")", "node");
        var focusNode = gooFlow.getItemInfo(focusId, "node");
        focusNode.name = row.user_truename + "(" + row.user_no + ")";
        focusNode.userID = row.ID;
        $("#div_win_choose_aud").window('close');
    }
    function backConChoose(row) {
        gooFlow.setName(focusId, row.ConditionName, "line")
        var focusLine = gooFlow.getItemInfo(focusId, "line");
        focusLine.name = row.ConditionName;
        focusLine.conditionID = row.ID;
        $("#div_win_choose_con").window('close');
    }
</script>

  後臺處理

 #region BaseFlowPicture
        public ActionResult BaseFlowPicture()
        {
            return View();
        }
        public ActionResult BacthSave(string node = "", string line = "", string area = "")
        {
            try
            {
                if (node != "")
                {
                    List<Q_HR_WorkFlow_Node> nodes = JSONStringToList<Q_HR_WorkFlow_Node>(node);
                    int s = nodes.Where(c => c.NodeType == "start").Count();
                    int e = nodes.Where(c => c.NodeType == "end").Count();
                    if (s != 1)
                        throw new Exception("請設置一個開始節點.");
                    if (e != 1)
                        throw new Exception("請設置一個結束節點.");
                    Q_HR_WorkFlow_NodeManage.BatchSave(nodes);
                }
                if (line != "")
                {
                    List<Q_HR_WorkFlow_Line> lines = JSONStringToList<Q_HR_WorkFlow_Line>(line);
                    Q_HR_WorkFlow_LineManage.BatchSave(lines);
                }
                if (area != "")
                {
                    List<Q_HR_WorkFlow_Area> areas = JSONStringToList<Q_HR_WorkFlow_Area>(area);
                    Q_HR_WorkFlow_AreaManage.BatchSave(areas);
                }
                return Json(new { status = 1 }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return Content(ex.Message);
            }
        }
        public string LoadWorkArea(int flowID = 0)
        {
            DataTable nodes = Q_HR_WorkFlow_NodeManage.GetList(flowID);
            DataTable lines = Q_HR_WorkFlow_LineManage.GetList(flowID);
            IList<Q_HR_WorkFlow_Area> areas = Q_HR_WorkFlow_AreaManage.GetList(flowID);
            string jsonStr = "{";
            string alt;
            //jsonStr += "\"initNum\":" + Q_HR_WorkFlow_NodeManage.GetInitNum() + ",";
            if (nodes.Rows.Count > 0)
            {
                jsonStr += "\"nodes\":{";
                foreach (DataRow row in nodes.Rows)
                {
                    alt = "false";
                    if (row["NodeType"].ToString() == "start" || row["NodeType"].ToString() == "end")
                        alt = "true";
                    jsonStr += "\"" + row["NodeID"] + "\":{"
                            + "\"ID\":" + row["ID"] + ""
                            + ",\"name\":\"" + row["UserName"] + "(" + row["user_no"] + ")\""
                            + ",\"userID\":" + row["UserID"] + ""
                            + ",\"type\":\"" + row["NodeType"] + "\""
                            + ",\"left\":" + row["NodeLeft"] + ""
                            + ",\"top\":" + row["NodeTop"] + ""
                            + ",\"width\":" + row["NodeWidth"] + ""
                            + ",\"height\":" + row["NodeHeight"] + ""
                            + ",\"alt\":" + alt + ""
                            + ",\"mark\":" + row["Marked"].ToString().ToLower() + ""
                            + "},";
                }
                jsonStr = jsonStr.TrimEnd(',') + "},";
            }
            if (lines.Rows.Count > 0)
            {
                jsonStr += "\"lines\":{";
                foreach (DataRow row in lines.Rows)
                {
                    jsonStr += "\"" + row["LineID"] + "\":{"
                            + "\"ID\":" + row["ID"] + ""
                            + ",\"name\":\"" + row["ConditionName"] + "\""
                            + ",\"conditionID\":" + row["ConditionID"] + ""
                            + ",\"type\":\"" + row["LineType"] + "\""
                            + ",\"from\":\"" + row["LineFrom"] + "\""
                            + ",\"to\":\"" + row["LineTo"] + "\""
                            + ",\"M\":" + row["LineM"] + ""
                            + ",\"mark\":" + row["Marked"].ToString().ToLower() + ""
                            + "},";
                }
                jsonStr = jsonStr.TrimEnd(',') + "},";
            }
            if (areas.Count > 0)
            {
                jsonStr += "\"areas\":{";
                foreach (Q_HR_WorkFlow_Area area in areas)
                {
                    jsonStr += "\"" + area.AreaID + "\":{"
                            + "\"ID\":" + area.ID + ""
                            + ",\"name\":\"" + area.AreaName + "\""
                            + ",\"left\":" + area.AreaLeft + ""
                            + ",\"top\":" + area.AreaTop + ""
                            + ",\"width\":" + area.AreaWidth + ""
                            + ",\"height\":" + area.AreaHeight + ""
                            + ",\"color\":\"" + area.AreaColor + "\""
                            + "},";
                }
                jsonStr = jsonStr.TrimEnd(',') + "},";
            }
            jsonStr = jsonStr.TrimEnd(',') + "}";
            return jsonStr;
        }
        public ActionResult DeleteFlowItem(string id, string type)
        {
            try
            {
                if (type.Equals("node"))
                    Q_HR_WorkFlow_NodeManage.DeleteFlowNode(id, type);
                else if (type.Equals("line"))
                    Q_HR_WorkFlow_LineManage.DeleteFlowLine(id, type);
                else if (type.Equals("area"))
                    Q_HR_WorkFlow_AreaManage.DeleteFlowArea(id, type);
                return Json(new { status = 1 }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return Content(ex.Message);
            }
        }
        #endregion

  

 

屬性名稱

做用

$id

裝載整個UI的DOM對象的ID。

$bgDiv

最父框架的DIV。

$tool

左側工具欄JQ對象。

$head

頂部欄標題標籤及工具欄按鈕。

$title

載入的流程圖的名稱。

$nodeRemark

左側工具欄中每一種結點或按鈕的說明文字,JSON格式,key爲按鈕類型名,value爲用戶自定義文字說明。

$nowType

當前要繪製的對象類型,開始時爲「cursor」,即不繪製任何元素,只是做爲鼠標指針進行元素選定。

$lineData={}

轉換線數據Map集,以id爲key,value爲詳細數據JSON對象。

$lineCount=0

轉換線數據的數量。

$nodeData={}

節點數據Map集,以id爲key,value爲詳細數據JSON對象。

$nodeCount=0

節點數據的數量。

$areaData={}

分組區數據Map集,以id爲key,value爲詳細數據JSON對象。

$areaCount=0

分組區數據的數量。

$lineDom={}

轉換線DOM展現對象Map集,以id爲key,value爲詳細在DOM對象。

$nodeDom={}

節點JQ展現對象Map集,以id爲key,value爲詳細在JO對象。

$areaDom={}

分組區JQ展現對象Map集,以id爲key,value爲詳細在JO對象。

$max

計算默認ID值的起始SEQUENCE,默認不填時爲1。

$focus

當前被選定的結點/轉換線ID,若是沒選中或者工做區被清空,則爲""。

$cursor

鼠標指針在工做區內的樣式,初始時爲default。

$editable

當前工做區是否可編輯,便是編輯模式仍是僅瀏覽模式。

$workArea

裝載結點/線條/分組區域的工做區。

$draw

畫矢量線條的容器,處於工做區中。

$group

僅用來裝配分組區域DOM元素的容器,處於工做區中。

$ghost

專門用在移動、重置大小等操做時,給用戶操做的半透明浮動區。

$textArea

雙擊操做對象後出現的浮動文本域,用來寫重命名方法setName所需的新名稱傳參。

$lineMove

操做移動折線的中段時用到的浮動DIV

$lineOper

選定一條轉換線後出現的浮動操做欄,有改變線的樣式和刪除線等按鈕。

//如下是當初始化的參數property.useOperStack=true且$editable=true時,才存在的屬性:

$undoStack=[]

「撤銷操做」棧。

$redoStack=[]

重作操做棧。

$isUndo

事務操做標誌位,內部調用

$deletedItem={}

在流程圖的編輯操做中被刪除掉的元素ID集合,元素ID爲KEY,元素類型(node,line.area)爲VALUE

 

[GooFlow對象供使用者調用的方法集]

方法名稱

做用

setNodeRemarks(remark)

設定左側工具欄中每一種結點或按鈕的說明文字,傳參是JSON格式,key爲按鈕類型名,value爲用戶自定義文字說明。

switchToolBtn(type)

切換左邊工具欄按鈕,傳參type表示切換成哪一種類型的按鈕

addNode(id,json)

增長一個結點,傳參json內容結構與$nodeData的每一個屬性單元同樣。

getItemInfo(id,type)

根據id這個KEY,和要獲取的數據類型type(有」node」,」line」,」area」三種取值),返回相應的結點json數據單元

blurItem()

取消全部結點/連線被選定的狀態

focusItem(id,bool)

選定某個結點/轉換線;傳參bool:TRUE決定了要觸發選中事件,FALSE則不觸發選中事件,多用在程序內部調用。

moveNode(id,left,top)

移動一個結點到一個新的位置

setName(id,name,type)

設置結點/連線/分組區域的文字信息;傳參id爲序列,name爲新的名稱,type爲改名對象的數據類型(有」node」,」line」,」area」三種取值)

resizeNode(id,width,height)

從新設置結點的尺寸,開始/結束類型的結點不支持該方法

delNode(id)

刪除結點

setTitle(text)

設置流程圖的名稱

loadData(data)

載入一組數據JSON格式的流程圖數據,傳參data中有title,nodes,lines,areas四個KEY的數據,還有一個可選屬性數據initNum:ID起始序列號最大數字+1——因爲繪製的新單元的ID都是按必定序列號及規則自動生成的,爲了防止新載入的數據的ID與編輯時新加入的ID值有重複,將給設計器對象對於新生成單元的ID序列一個新的起始序列號;若是傳參JSON中沒有這個屬性,也能夠在調用loadData方法前修改設計器對象的$max屬性值(其實loadData方法執行時會檢查傳參中若是有initNum時,將自動給設計器對象的$max賦上此值);

nodes,lines,areas都爲一組{key:value}式的Map數據,內容結構分別與GooFlow對象屬性中的$nodeData,$lineData,$areaData一致.

loadDataAjax(para)

用AJAX方式,遠程讀取一組數據;

參數para爲JSON結構,與JQUERY中$.ajax()方法的傳參同樣

須要後臺異步返回JSON格式的msg結果,其內容格式與loadData方法的傳參同樣。

exportData()

把畫好的結束導出到一個本函數返回的變量中(其實也能夠直接訪問GooFlow對象的$nodeData,$lineData,$areaData這三個JSON屬性)

exportAlter()

//只把本次編輯流程圖中做了變動(包括增刪改)的元素導出到一個變量中,以方便用戶每次編輯載入的流程圖後只獲取變動過的數據

transNewId(oldId,newId,type)

變動元素的ID,通常用於快速保存後,將後臺返回新元素的ID更新到頁面中;type爲元素類型(節點,連線,區塊)

clearData()

清空工做區及已載入的數據

destrory()

銷燬本身

addLine(id,json)

增長一條線,傳參json內容結構與$lineData的每一個屬性單元同樣。

setLineType(id,newType)

從新設置連線的樣式. 傳參newType的取值有:"sl"直線, "lr"中段可左右移動型折線, "tb"中段可上下移動型折線

setLineM(id,M)

設置折線中段的X座標值(可左右移動時)或Y座標值(可上下移動時);直線不支持此方法

delLine(id)

刪除轉換線

markItem(id,type,mark)

//用顏色標註/取消標註一個結點或轉換線,經常使用於顯示重點或流程的進度。

       //這是一個在編輯模式中無用,可是在純瀏覽模式中很是有用的方法,實際運用中可用於跟蹤流程的進度。

//傳參:id是操做單元對象惟一序列號;type是操做單元類型(「node」或者」line」,分組區域不支持此方法);mark爲布爾值,表示是否標註/取消標註某個ID值的數據單元對象

addArea(id,json)

增長一個分組區域,傳參json內容結構與$areaData的每一個屬性單元同樣。

moveArea(id,left,top)

移動分組區域到新的位置上.

delArea(id)

刪除分組區域

setAreaColor(id,color)

設置分組區域的顏色,傳參color爲顏色樣式,只有」red」,」yellow」,」blue」,」green」四種取值

resizeArea(id,width,height)

從新設置區分組區域的尺寸

      

reinitSize(width,height)

重構整個流程圖設計器的寬高,在瀏覽器窗口大小改變或者父容器寬高改變時,執行這個方法能讓設計器從新適應新的寬高顯示。

//如下是當初始化的參數property.useOperStack=true時,才存在的方法:

pushOper(funcName,paras)

僅供內部方法調用的方法:把對工做區內的數據單元編輯操做(增/刪/改/重命名/移動/標註等)加入整條管理棧中,好進入撤銷/重作的控制;

注意:將爲了節省瀏覽器內存空間,undo/redo中的操做緩存棧,最多隻可放40步操做;超過40步時,將自動刪掉最舊的一個緩存。

pushExternalOper

(func,jsonPara)

//將外部的方法加入到GooFlow對象的事務操做堆棧中,在事後的undo/redo操做中能夠進行控制,通常用於對流程圖之外的附加信息進行編輯的事務撤銷/重作控制;

//傳參func爲要執行方法對象,jsonPara爲外部方法僅有的一個面向字面的JSON傳參或者數據,由JSON對象或數組帶入全部要傳的信息;

//提示:爲了讓外部方法可以被UNDO/REDO,須要在編寫這些外部方法實現時,加入對該方法執行後效果回退的另外一個執行方法的pushExternalOper。

undo()

撤銷最近一次操做

redo()

重作最近一次被撤銷的操做

相關文章
相關標籤/搜索