123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595 |
- <!doctype html>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>流程图</title>
- <!--#include file="common/_header.html"-->
- <link rel="stylesheet" type="text/css" href="scripts/workflow/tipsy.css" />
- <link rel="stylesheet" type="text/css" href="lib/select2/select2.min.css" />
- <style>
- body {
- position: fixed;
- top: 0;
- bottom: 0;
- left: 0;
- right: 0;
- margin: 0;
- padding: 0;
- font-family:tahoma "microsoft yahei";
- }
-
- .live.map {
- width: 100%;
- height: 100%;
- }
-
- .live.map text {
- font-weight: 300;
- font-size: 14px;
- }
-
- .live.map .node rect {
- stroke-width: 1.5px;
- stroke: #bbb;
- fill: #666;
- }
- svg {
- width: 100%;
- height: 100%;
- overflow: hidden;
- }
-
- .live.map .status {
- height: 100%;
- width: 15px;
- display: block;
- float: left;
- border-top-left-radius: 5px;
- border-bottom-left-radius: 5px;
- margin-right: 4px;
- }
-
- .live.map .start .status {
- background-color: green;
- }
-
- .live.map .blank .status {
- background-color: white;
- }
- .live.map .ignore .status {
- background-color: #aaaaaa;
- }
-
-
- .live.map .end .status {
- background-color: red;
- }
-
- .live.map .node g div {
- width: 200px;
- height: 40px;
- color: #fff;
- }
- .live.map .userTask{
- cursor:pointer;
- }
-
- .live.map .taskName {
- display: inline-block;
- width: 200px;
- padding:2px;
- }
-
- .live.map .assiginee {
- display: block;
- float: left;
- width: 130px;
- height: 20px;
- font-size: 12px;
- margin-top: 2px;
- color:cornsilk;
- }
-
- .live.map .edgeLabel text {
- width: 50px;
- fill: #fff;
- }
-
- .live.map .edgePath path {
- stroke: #999;
- stroke-width: 1.5px;
- fill: #999;
- }
- .live.map .node g .gateway{
- width : 50px;
- height : 50px;
- border-radius: 100%;
- }
- .flex-container{
- display: flex;
- flex-direction: row;
- height:100%;
- width:100%;
- }
- #diagram{
- flex:1;
- }
- .right-side{
- display: flex;
- flex-direction: column;
- border-left:1px dotted black;
- }
- #propertyPanel{
- position:relative;
- width:400px;
- padding:5px;
- overflow: auto;
- flex:1;
- }
- .input-text{
- height:30px;
- border-radius: 4px;
- border: 1px solid #aaa;
- width:100%;
- }
- dt{
- font-weight: bold;
- height:30px;
- line-height:30px;
- }
- dd {
- margin-inline-start:0px;
- }
- </style>
- </head>
- <body>
- <div class="flex-container">
- <div id="diagram" class="live map">
- <svg style="width:100%;height:100%;"></svg>
- </div>
- <div class="right-side">
- <div id="propertyPanel">
- <h3>属性设置</h3>
- <dl>
- <dt>当前步骤:</dt>
- <dd>
- <input type="text" v-model="step.title" readonly class="input-text"/>
- </dd>
- <dt>当前序号:</dt>
- <dd>
- <input type="number" v-model="step.no" class="input-text"/>
- </dd>
- <dt>是否忽略:</dt>
- <dd>
- <select class="select" v-model="step.ignore">
- <option value="1">是</option>
- <option value="0" selected>否</option>
- </select>
- </dd>
- <dt>待办人设置:</dt>
- <dd>
- <select id="assigneeSelect" style="width:100%;" multiple>
- </select>
- </dd>
- <dt>待办人角色设置:</dt>
- <dd>
- <select id="assigneeRoleSelect" style="width:100%;" multiple>
- </select>
- <!-- </dd>
- <dt>完成后通知人:</dt>
- <dd>
- <select id="noticeSelect" style="width:100%;" multiple>
- </select>
- </dd>
- <dt>完成后通知角色设置:</dt>
- <dd>
- <select id="noticeRoleSelect" style="width:100%;" multiple>
- </select>
- </dd> -->
- <dt>预估完成人天设置:</dt>
- <dd><input type="number" class="input-text" v-model="step.day"/>人天</dd>
- <dt>待办事项:</dt>
- <dd>
- <table width="100%" class="table table-border table-bordered radius">
- <thead>
- <tr>
- <th>序号</th>
- <th>事项名称</th>
- <th>操作</th>
- </tr>
- </thead>
- <tr v-for="(todo,index) in todoListFilter(todoList)">
- <td>{{index+1}}</td>
- <td><input type="text" v-model="todo.detail" class="input-text"/></td>
- <td><button @click="removeTodo(index)" class="btn btn-default radius">删除</button></td>
- </tr>
- </table>
- <button @click="addTodo()" class="btn btn-default radius">新增</button>
- </dd>
- </dl>
- </div>
- <div style="text-align:center;height:50px;">
- <button onclick="submit()" class="btn btn-primary radius size-L">保存</button>
- </div>
- </div>
- </div>
- <script id="taskTmpl" type="text/html">
- <div id="task_{{id}}" class="userTask {{className}}" onclick="configTask('{{id}}','{{name}}')">
- <span class="status"></span>
- <span class="taskName" id="{{id}}">{{name}}</span>
- <span class="assiginee">{{remark}}</span>
- </div>
- </script>
- <script id="gatewayTmpl" type="text/html">
- <p class="gateway"></p>
- </script>
- <!--#include file="common/_footer.html"-->
- <script type="text/javascript" src="scripts/workflow/d3.v3.min.js" charset="utf-8"></script>
- <script type="text/javascript" src="scripts/workflow/dagre-d3.min.js" ></script>
- <script type="text/javascript" src="scripts/workflow/tipsy.js" ></script>
- <script type="text/javascript" src="scripts/global.js"></script>
- <script type="text/javascript" src="lib/select2/select2.full.js"></script>
- <script type="text/javascript" src="lib/select2/select2.zh-CN.js"></script>
- <script type="text/javascript" src="lib/vue/vue.js"></script>
- <script type="text/javascript" src="lib/vue/directive/vue-select2.js"></script>
- <script type="text/javascript">
- var procDefKey = getQueryString("procDefKey");
- var templateId = getQueryString("templateId");
- </script>
- <script type="text/javascript">
- $(document).ready(function(){
- $.get(global_backend_url + "/procDef/loadDiagram",
- {
- procDefKey : procDefKey,
- templateId : templateId
- },function(rs){
- var data = rs.data;
- createDiagram(data);
- },"json");
- });
- function createDiagram(data){
- // Create a new directed graph
- var g = new dagreD3.graphlib.Graph();
-
- g.setGraph({
- nodesep: 70,
- ranksep: 50,
- rankdir: "TB",
- marginx: 20,
- marginy: 20
- });
-
- //start
- for(var i=0;i<data.startNodeList.length;i++){
- var node = data.startNodeList[i];
- g.setNode(node.id, {
- labelType: "html",
- label:template("taskTmpl",{
- id:"start",
- name:node.name,
- className:"start"
- }),
- rx: 5,
- ry: 5,
- padding: 0
- });
- }
-
- //end
- for(var i=0;i<data.endNodeList.length;i++){
- var node = data.endNodeList[i];
- g.setNode(node.id, {
- labelType: "html",
- label:template("taskTmpl",{
- id:"end",
- name:node.name,
- className:"end"
- }),
- rx: 5,
- ry: 5,
- padding: 0
- });
- }
-
- //用户任务
- for(var i=0;i<data.taskList.length;i++){
- var task = data.taskList[i];
- task.className = "blank";
- if(task.step!=null) {
- if(!!task.step.ignore){
- task.remark = "已设置(自动忽略)";
- task.className = "ignore";
- }
- else{
- task.remark = "已设置(正常)";
- }
- }
- else{
- task.remark = "未设置";
- }
- g.setNode(task.id, {
- labelType: "html",
- label:template("taskTmpl",task),
- rx: 5,
- ry: 5,
- padding: 1
- });
- }
- //独占网关
- for(var i=0;i<data.exclusiveGatewayList.length;i++){
- var gateway = data.exclusiveGatewayList[i];
- g.setNode(gateway.id, {
- shape: 'diamond',
- style: "fill: #fff; stroke: #000"
- });
- }
- //并行网关
- for(var i=0;i<data.parallelGatewayList.length;i++){
- var gateway = data.parallelGatewayList[i];
- g.setNode(gateway.id, {
- label:'',
- shape: 'diamond',
- style: "fill: #fff; stroke: #000"
- });
- }
-
- //连接线
- for(var i=0;i<data.seqFlowList.length;i++){
- var seqFlow = data.seqFlowList[i];
-
- g.setEdge(seqFlow.sourceRef, seqFlow.targetRef,{
- label: seqFlow.name
- });
- }
-
- // Create the renderer
- var render = new dagreD3.render();
-
- // Set up an SVG group so that we can translate the final graph.
- var svg = d3.select("svg"),
- inner = svg.append("g");
-
- // Set up zoom support
- var zoom = d3.behavior.zoom().on("zoom", function() {
- inner.attr("transform", "translate(" + d3.event.translate + ")" + "scale(" + d3.event.scale + ")");
- });
-
- svg.call(zoom);
-
- // Run the renderer. This is what draws the final graph.
- render(inner, g);
-
- // Zoom and scale to fit
- // Zoom and scale to fit
- var graphWidth = g.graph().width + 80;
- var graphHeight = g.graph().height + 40;
- var width = parseInt(svg.style("width").replace(/px/, ""));
- var height = parseInt(svg.style("height").replace(/px/, ""));
- // var zoomScale = Math.min(width / graphWidth, height / graphHeight);
- var zoomScale = 1;
- // var translate = [(width/2) - ((graphWidth*zoomScale)/2), (height/2) - ((graphHeight*zoomScale)/2)];
- var translate = [(width/2) - ((graphWidth*zoomScale)/2), 0];
- zoom.translate(translate);
- zoom.scale(zoomScale);
- zoom.event(svg);
- }
- </script>
- <script type="text/javascript">
- var vm = new Vue({
- el : "#propertyPanel",
- data : {
- step: {
- title:'',
- ignore:0,
- day:0
- },
- assigneeList: [],
- noticeList: [],
- todoList: []
- },
- methods: {
- addTodo : function(){
- this.todoList.push({
- detail: "",
- delFlag: false
- });
- },
- removeTodo : function(index){
- // this.todoList.splice(index,1);
- this.todoList[index].delFlag = true;
- },
- todoListFilter:function(todoList){
- return todoList.filter(function (todo) {
- return !todo.delFlag;
- })
- },
- }
- });
- var userOptions = {
- ajax: {
- url: global_backend_url + "/jpAdmin/selectUser",
- dataType: 'json',
- delay: 250,
- method:'post',
- allowClear: false,
- processResults: function (data) {
- var results = data.map(function(item){
- return {
- id : item.userId,
- text : item.realName,
- userName: item.userName,
- orgName : item.orgName
- }
- });
- return {
- results: results
- }
- }
- },
- language: "zh-CN",
- templateResult: function (state) {
- var html = "<div>";
- html += "<strong>姓名:" + state.text + "</strong>(" + state.userName + ")<br/>";
- html += "单位:" + state.orgName;
- html += "</div>";
- return $(html);
- }
- };
- var roleOptions = {
- ajax: {
- url: global_backend_url + "/role/selectRole",
- dataType: 'json',
- delay: 250,
- method:'post',
- processResults: function (data) {
- console.log(data);
-
- var results = data.map(function(item){
- return {
- id : item.roleId,
- text : item.roleDesc
- }
- });
- return {
- results: results
- }
- }
- },
- language: "zh-CN",
- templateResult: function (state) {
- var html = "<div>";
- html += state.text;
- html += "</div>";
- return $(html);
- },
- allowClear: false
- };
- function select2_init(el,options){
- $(el).select2(options).on('select2:select', function(){
- setTimeout(function(){
- $(".select2-search__field", $(el).parent()).focus();
- });
- });
- }
- select2_init($("#assigneeSelect"),userOptions);
- select2_init($("#assigneeRoleSelect"),roleOptions);
- function initSelectedUsers(el,userList,value){
- $('option', el).remove();
- userList.forEach(function(user){
- var newOption = new Option(user.realName, user.userId, false, false);
- $(el).append(newOption);
- });
- $(el).val(value).trigger('change');
- }
- function initSelectedRoles(el,roleList,value){
- $('option', el).remove();
- roleList.forEach(function(role){
- var newOption = new Option(role.roleDesc, role.roleId, false, false);
- $(el).append(newOption);
- });
- $(el).val(value).trigger('change');
- }
- function configTask(taskDefKey,taskName){
- if(taskDefKey.length==0 || taskDefKey=="start" || taskDefKey=="end"){
- return;
- }
- var loadingIndex = layer.load(1, {shade: [0.2,'#fff']});
- $.get(global_backend_url + "/procDefTmpl/step/detail",{
- taskDefKey : taskDefKey,
- templateId : templateId
- },function(resp){
- layer.close(loadingIndex);
- var data = resp.data;
- vm.step = data.dto.step;
- vm.step.title = taskName;
- initSelectedUsers($("#assigneeSelect"),data.assignedList,data.dto.assigneeList);
- initSelectedRoles($("#assigneeRoleSelect"),data.assignedRoleList,data.dto.assigneeRoleList);
- vm.todoList = data.dto.todoList;
- },"json");
- }
- function submit(){
- if(vm.step.no==null || vm.step.no.length==0){
- layer.msg("请先设置序号!",{icon:2});
- return;
- }
- var loadingIndex = layer.load(0, {shade: [0.4,'#fff']});
- $.ajax({
- url: global_backend_url + "/procDefTmpl/step/save",
- type: "POST", //请求类型
- data: JSON.stringify({
- step: vm.step,
- assigneeList: $('#assigneeSelect').val(),
- assigneeRoleList: $('#assigneeRoleSelect').val(),
- todoList: vm.todoList
- }),
- dataType:"json",
- contentType:"application/json",
- success: function(resp){
- layer.close(loadingIndex);
- if(resp.result){
- layer.msg("保存成功!",{icon:1,time:2000});
-
- var task = {};
- task.remark = "已设置(" + (vm.step.ignore==1 ? "自动忽略" : "正常") + ")";
- task.step = vm.step;
- task.id = vm.step.taskDefKey;
- task.name = vm.step.title;
- $("#task_" + task.id).html(template("taskTmpl",task));
- }
- else{
- layer.msg("保存失败!" + resp.message,{icon:1});
- }
- }
- });
- }
- </script>
- </body>
- </html>
|