angular流程引擎集成


工作流在oa和erp中十分常見,現有成熟的工作流通常是在客戶端實現的,web實現工作流的案例十分稀少。要實現web工作流必須要有強大的流程設計器,這里為大家介紹一款基於angular的流程控件,其功能十分強大,可直接開發在線流程設計工具。

流程設計效果如下:

 該流程工具使用的是syncfusion旗下的angular組件開發,需要先安裝組件: @syncfusion/ej2-angular-diagrams

angular項目中添加demo-flow組件,在demo-flow目錄中添加script文件夾,script中粘貼diagram-common.js

准備就緒后開始布局流程頁面,布局代碼如下:

<script src="script/diagram-common.ts"></script>
<div class="m-portlet m-portlet--mobile">
    <div class="m-portlet__head">
        <div class="m-portlet__head-caption">
            <div class="m-portlet__head-title">
                <h3 class="m-portlet__head-text">
                    流程設計測試
                </h3>
            </div>
        </div>
    </div>
    <div class="diagram-serialization" style="width: 100%;height: 10%">
        <ejs-toolbar width="100%" (clicked)="onClicked($event)">
            <e-items>
                <e-item text='New' tooltipText='New' prefixIcon='e-ddb-icons e-new'></e-item>
                <e-item type='Separator'></e-item>
                <e-item text='Save' tooltipText='Save' prefixIcon='e-ddb-icons e-save'></e-item>
                <e-item type='Separator'></e-item>
                <e-item text='Load' tooltipText='Load' prefixIcon='e-ddb-icons e-open'></e-item>
                <e-item type='Separator'></e-item>
            </e-items>
        </ejs-toolbar>
    </div>
    <div style="width:100%;height: 80%">
        <div id="palette-space" class="sb-mobile-palette">
            <ejs-symbolpalette id="symbolpalette" [enableAnimation]='enableAnimation' [expandMode]='expandMode'
                [palettes]='palettes' (created)='create($event)' width="100%" height="700px" [symbolHeight]=60
                [symbolWidth]=60 [symbolMargin]='symbolMargin' [getSymbolInfo]='getSymbolInfo'
                [getNodeDefaults]='getSymbolDefaults'>
            </ejs-symbolpalette>
        </div>

        <div id="diagram-space" class="sb-mobile-diagram">
            <div class="content-wrapper">
                <ejs-diagram #diagram id="diagram" width="100%" height="700px" [snapSettings]='snapSettings'
                    [getConnectorDefaults]='getConnectorDefaults' (doubleClick)="doubleClick($event)">
                    <e-nodes>
                        <e-node id='Start' [height]=50 [width]=100 [shape]='terminator' [offsetX]=250 [offsetY]=80
                            [style]='terminatorStyle'>
                            <e-node-annotations>
                                <e-node-annotation content='Start'>
                                </e-node-annotation>
                            </e-node-annotations>
                        </e-node>
                        <e-node id='Alarm' [height]=50 [width]=100 [shape]='process' [offsetX]=250 [offsetY]=160
                            [style]='processStyle'>
                            <e-node-annotations>
                                <e-node-annotation content='Alarm Rings'>
                                </e-node-annotation>
                            </e-node-annotations>
                        </e-node>
                        <e-node id='Ready' [height]=50 [width]=100 [shape]='decision' [offsetX]=250 [offsetY]=240
                            [style]='decisionStyle'>
                            <e-node-annotations>
                                <e-node-annotation content='Ready to Get Up?'>
                                </e-node-annotation>
                            </e-node-annotations>
                        </e-node>
                        <e-node id='Climb' [height]=50 [width]=100 [shape]='process' [offsetX]=250 [offsetY]=330
                            [style]='processStyle'>
                            <e-node-annotations>
                                <e-node-annotation content='Climb Out of Bed'>
                                </e-node-annotation>
                            </e-node-annotations>
                        </e-node>
                        <e-node id='End' [height]=50 [width]=100 [shape]='terminator' [offsetX]=250 [offsetY]=430
                            [style]='terminatorStyle'>
                            <e-node-annotations>
                                <e-node-annotation content='End'>
                                </e-node-annotation>
                            </e-node-annotations>
                        </e-node>
                        <e-node id='Relay' [height]=50 [width]=100 [shape]='delay' [offsetX]=450 [offsetY]=160
                            [style]='delayStyle'>
                            <e-node-annotations>
                                <e-node-annotation content='Relay'>
                                </e-node-annotation>
                            </e-node-annotations>
                        </e-node>
                        <e-node id='Hit' [height]=50 [width]=100 [shape]='process' [offsetX]=450 [offsetY]=240
                            [style]='processStyle'>
                            <e-node-annotations>
                                <e-node-annotation content='Hit Snooze Button'>
                                </e-node-annotation>
                            </e-node-annotations>
                        </e-node>
                    </e-nodes>
                    <e-connectors>
                        <e-connector id='connector1' sourceID='Start' targetID='Alarm'>
                        </e-connector>
                        <e-connector id='connector2' sourceID='Alarm' targetID='Ready'>
                        </e-connector>
                        <e-connector id='connector3' sourceID='Ready' targetID='Climb'>
                            <e-connector-annotations>
                                <e-connector-annotation content='Yes' [style]='connectorTextStyle'>
                                </e-connector-annotation>
                            </e-connector-annotations>
                        </e-connector>
                        <e-connector id='connector4' sourceID='Climb' targetID='End'>
                        </e-connector>
                        <e-connector id='connector5' sourceID='Ready' targetID='Hit'>
                            <e-connector-annotations>
                                <e-connector-annotation content='No' [style]='connectorTextStyle'>
                                </e-connector-annotation>
                            </e-connector-annotations>
                        </e-connector>
                        <e-connector id='connector6' sourceID='Hit' targetID='Relay'>
                        </e-connector>
                        <e-connector id='connector7' sourceID='Relay' targetID='Alarm'>
                        </e-connector>
                    </e-connectors>
                </ejs-diagram>
            </div>
            <ejs-uploader #defaultupload id='fileupload' (success)='onUploadSuccess($event)'
                [asyncSettings]='asyncSettings'></ejs-uploader>
        </div>
    </div>


    <div bsModal #createOrEditModal="bs-modal" class="modal fade" tabindex="-1" role="dialog"
        aria-labelledby="createOrEditModal" aria-hidden="true" [config]="{backdrop:'static'}">
        <div class="modal-dialog modal-lg">
            <div class="modal-content">
                <div class="modal-header">
                    <h4 class="modal-title">
                        <span>修改節點</span>
                    </h4>
                    <button type="button" class="close" (click)="close()" attr.aria-label="關閉">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    <div class="form-group">
                        <label>Id</label>
                        <input type="text" class="form-control" [(ngModel)]="selectItem.id" readonly>
                    </div>
                    <div class="form-group" [hidden]="selectItem.type!='node'">
                        <label>名稱*</label>
                        <input type="text" class="form-control" [(ngModel)]="selectItem.name">
                    </div>
                    <div class="form-group" [hidden]="selectItem.type!='node'">
                        <label>執行權限</label>
                        <select class="form-control" [formControl]="selectedState">
                            <option value="">選擇執行權限</option>
                            <option value="1">所有人</option>
                            <option value="2">指定角色</option>
                        </select>
                    </div>
                    <div class="form-group" [hidden]="selectItem.type!='node' || selectedState.value!='2'">
                        <label class="m-checkbox">
                            <input type="checkbox">
                            部門主管
                            <span></span>
                        </label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                        <label class="m-checkbox">
                            <input type="checkbox">
                            部門經理
                            <span></span>
                        </label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    </div>
                    <div class="form-group" [hidden]="selectItem.type!='connector'">
                        <label>執行條件</label><br>
                        <p-radioButton name="radGroup" value="yes" label="通過" [(ngModel)]="condition"></p-radioButton>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                        <p-radioButton name="radGroup" value="no" label="不通過" [(ngModel)]="condition"></p-radioButton>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                        <p-radioButton name="radGroup" value="scope" label="執行范圍" [(ngModel)]="condition"></p-radioButton>
                    </div>
                    <div class="form-row" [hidden]="selectItem.type!='connector' || condition!='scope'">
                        <div class="form-group col-md-4">
                            <label>運算符</label>
                            <select class="form-control" [formControl]="operator">
                                <option value="">選擇運算符</option>
                                <option value="大於">大於</option>
                                <option value="小於">小於</option>
                                <option value="等於">等於</option>
                            </select>
                        </div>
                        <div class="form-group col-md-4">
                            <label class=""></label>
                            <div class="">
                                <input type="number" [(ngModel)]="scopeValue" class="form-control" placeholder="值">
                            </div>
                        </div>
                        <div class="form-group col-md-4">
                            <label>單位</label>
                            <select class="form-control" [formControl]="unit">
                                <option value="">選擇單位</option>
                                <option value="天"></option>
                                <option value="小時">小時</option>
                                <option value="元"></option>
                            </select>
                        </div>
                    </div>

                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" (click)="close()">關閉</button>
                    <button type="button" class="btn btn-primary" (click)="save()">
                        <i class="fa fa-save"></i><span>保存</span>
                    </button>
                </div>
            </div>

        </div>
    </div>
</div>

流程頁面模板中加入了雙擊節點和連接器的事件,如果要開發工作流必須要對事件作處理,僅開發流程設計器則需要取消雙擊事件以免影響使用。

事件處理如下:

    public doubleClick(args: IDoubleClickEventArgs): void {
        var node = this.diagram.selectedItems.nodes[0];
        var connector = this.diagram.selectedItems.connectors[0];
        if (node) {
            this.selectItem.id = node.id;
            this.selectItem.name = node.annotations[0].content;
            this.selectItem.type = 'node';

            this.modal.show();
        }
        if (connector) {
            this.selectItem.id = connector.id;
            this.selectItem.name = connector.annotations[0].content;
            this.selectItem.type = 'connector';
            this.modal.show();
        }
    }

    save(): void {
        if (this.diagram.selectedItems.nodes[0]) {
            this.diagram.selectedItems.nodes[0].annotations[0].content = this.selectItem.name;
            this.close();
        }
        if (this.diagram.selectedItems.connectors[0]) {
            if(this.condition=='yes'){
                this.diagram.selectedItems.connectors[0].annotations[0].content="通過";
            }
            if(this.condition=='no'){
                this.diagram.selectedItems.connectors[0].annotations[0].content="不通過";
            }
            if(this.condition=='scope'){
                this.diagram.selectedItems.connectors[0].annotations[0].content=this.operator.value+' '+this.scopeValue+' '+this.unit.value;
            }
            this.close();
        }
    }

    close(): void {
        this.modal.hide();
    }

流程器顯示和雙擊功能如下:

 

 

 

 

到這里angular的流程設計器已經介紹完畢,要實現工作流機制需要針對自己的系統作表單設計和業務關聯,相關的實現文檔有很多,這里就不過多介紹了。目前功能還比較粗糙,優化完后我會對這些功能進行開源,感興趣的可以后續關注。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM