bpmn.js 18.8 KB
Newer Older
fukai committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462

function cloneObj (obj) {
    var str;
    var newObj = obj.constructor === Array ? [] : {};
    if (typeof obj !== 'object') {
        return;
    } else if (JSON) {
        str = JSON.stringify(obj);  //系列化对象
        newObj = JSON.parse(str);   //还原
    } else {
        for (var i in obj) {
            newObj[i] = typeof obj[i] === 'object' ? cloneObj(obj[i]) : obj[i];
        }
    }
    return newObj;
}

/**
 * 删除线时,更新对应起始环节的poin_lineCount(以它起始的线的总数)和poin_cacheIndexs(缓存被删除的线的id _TR后索引值)
 * @param {transId} 线id 
 * @param {elementRegistry} 通过它的get方法来获取图形信息 
 */
function deleteConnection(transId, elementRegistry) {
    if (!transId || (typeof transId === 'string' && transId.indexOf('_TR') === -1)) {
        return;
    }
    if (transId.indexOf('_TR_') > -1) {
        const actId = transId.split('_TR_')[0];
        const index = Number(transId.split('_TR_')[1]);
        const actEl = elementRegistry.get(actId);
        if (!actEl) {
            return;
        }
        // 删除的为最后一条线,则只要更新poin_lineCount即可
        if (index + 1 === actEl.poin_lineCount) {
            actEl.poin_lineCount--;
        } else {
            // 删除的为中间某些线,不更新poin_lineCount,缓存删除的Index,再生成线时优先从cacheIndexs中取数
            if (actEl.poin_cacheIndexs) {
                let poin_cacheIndexs = actEl.poin_cacheIndexs
                if (index < poin_cacheIndexs[0]) {
                    poin_cacheIndexs.unshift(index)
                } else if (index > poin_cacheIndexs[poin_cacheIndexs.length - 1]) {
                    poin_cacheIndexs.push(index)
                } else {
                    const cacheIndex = poin_cacheIndexs.findIndex(item => item > index)
                    if (cacheIndex > -1) {
                        poin_cacheIndexs.splice(cacheIndex, 0, index)
                    }
                }
            } else {
                actEl.poin_cacheIndexs = [index];
            }
        }
    } else {
        const actEl = elementRegistry.get(transId.split('_TR')[0]);
        if (!actEl) {
            return;
        }
        // 删除的为第一条线
        // 只有这一条线,则只要更新poin_lineCount即可
        if (1 === actEl.poin_lineCount) {
            //delete actEl.poin_lineCount;
            actEl.poin_lineCount = 0;
        } else {
            // 不只有这一条线,需要缓存这个index
            if (actEl.poin_cacheIndexs) {
                actEl.poin_cacheIndexs.unshift(0)
            } else {
                actEl.poin_cacheIndexs = [0];
            }
        }
    }
}

const bpmn = {
    state: {
        //环节编辑打开和关闭状态
    	nodeVisible: false,
    	//2021-10-15用于批量编排环节查看弹框打开和关闭状态
    	nodeLook:false,
    	//环节自身信息
        nodeInfo: {},
        //modeler实例 用来获取modeling(更新节点信息用的)和elementRegistry(根据id获取节点图形对象用的)
        bpmnModeler:null,
        //任务流程数据
        taskJson:{
            "unitFlag":"",
        	"id":"",
        	"flowId":"",
        	"flowDesc":"",
        	"flowCron":"",
        	"addTime":"",
        	"updateTime": null,
        	"author":"",
        	"jobGroup":"",
        	"lastVersion": "",
        	"flowXmlData":"",//xml数据
        	"flowNodeData":[],//环节数据
        	"connects":[],//add by lujing2021-07-09 批量线分支sequenceFlowId-json数据
        	"fileCoordFlag": 0,
	    	"fileCron": "",
	    	"filePath": "",
	    	"fileBean": "",
	    	"alarmNumLimit": "",//告警次数add by 陆静2021-09-15
	    	"expectExecuteTimes": "",//耗时add by 陆静2021-09-15
	    	"flowBlackDate":"",// 黑名单 by ynj2021-12-02
		"temporaryFlag":0,// 是否临时任务add by myl 2021-12-1
	    	"deadTime":"",
	    	"flowParam": "" //流程参数
        },
        //工作流程图保存数据  bpmn-xml 和表单数据
        bpmnJson: {
        	"packageId":"",
            "bpmnData":"",
            "formData":{
                "id":"",
                "name":"",
                "createDate":"",
                "proPriority":"5",
                "proDescription":"",
                "author":"",
                "todoCenter":"0",
        	    "msgCenter":"0",
                "wfpEventListener":[],
                "remindProcessInfo":{
                    "remindTimeD":"",
                    "remindTimeH":"",
                    "remindTimeM":"",
                    "remindTimeS":"",
                    "remindEmailWay":"",
                    "remindMessageWay":"",
                    "remindCalendar":"0",
                    "remindCount":"",
                    "remindRateD":"",
                    "remindRateH":"",
                    "remindRateM":"",
                    "remindRateS":"",
                    "remindStarter":"",
                    "remindAll":""
                },
                "formName":"",
                "pojoName":"",
                "proData":[],
                "participant":[],
                "transList":[],
                "autoInterfaces":[],
                "actList":[]
            }
        }
    },
    mutations: {
        TOGGLENODEVISIBLE: (state, visible) => {
            state.nodeVisible = visible
        },
        TOGGLENODELOOK: (state, visible) => {
            state.nodeLook = visible
        },
        SETNODEINFO: (state, info) => {
            state.nodeInfo = info
        },
        SETBPMNMODELER: (state, info) => {
            state.bpmnModeler = info
        },
        // add by lidan @2020-05-09
        SETBPMNJSON: (state, info) => {
            state.bpmnJson = info
        },
        SET_BPMN_DATA: (state, data) => {
            state.bpmnJson.bpmnData = data
        },
        //增加发布流程 选择版本号传递给后台
        SETPACKAGEID: (state, info) => {
            state.bpmnJson.packageId = info
        },
        // 基本信息 - 基本信息
        SET_BASE_INFO: (state, info) => {
            const formData = state.bpmnJson.formData;
            formData.id = info.id;
            formData.name = info.name;
            formData.createDate = info.createDate;
            formData.proPriority = info.proPriority;
            formData.proDescription = info.proDescription;
            formData.author = info.author;
            formData.todoCenter = info.todoCenter?info.todoCenter:'0';
            formData.msgCenter = info.msgCenter?info.msgCenter:'0';
        },
        // 基本信息 - 触发事件
        SET_ACTIVITY_TRIGGER: (state, data) => {
            state.bpmnJson.formData.wfpEventListener = [];
            const wfpEventListener = state.bpmnJson.formData.wfpEventListener;
            data.wfpEventListener.forEach(item => {
                wfpEventListener.push({
                    "dataId": item.dataId,
			        "clsPath": item.clsPath
                })
            })
            state.bpmnJson.formData.remindProcessInfo = JSON.parse(JSON.stringify(data.remindProcessInfo));
        },
        // 基本信息 - 流程相关
        SET_RELATIVE_INTERFACE: (state, data) => {
            const formData = state.bpmnJson.formData;
            formData.formName = data.formName;
            formData.pojoName = data.pojoName;
            formData.proData = [];
            data.proData.forEach(item => {
                formData.proData.push({
                    "id": item.id,
                    "name": item.name,
                    "type": item.type,
                    "length": item.length,
                    "isArray": item.isArray,
                    "initValue": item.initValue
                })
            })
        },
        // 接口定义
        SET_AUTO_INTERFACES: (state, data) => {
            state.bpmnJson.formData.autoInterfaces = [];
            const autoInterfaces = state.bpmnJson.formData.autoInterfaces;
            if (data instanceof Array) {
                data.forEach(item => {
                    if (item.children && item.children instanceof Array) {
                        item.children.forEach(childrenItem => {
                            const info = JSON.parse(JSON.stringify(childrenItem.info));
                            delete info['type'];
                            delete info['origName'];
                            info['autoFormList'] = [];
                            if (childrenItem.data && childrenItem.data.length > 0) {
                                childrenItem.data.forEach(listItem => {
                                    info['autoFormList'].push({
                                        "name": listItem.name,
                                        "javaType": listItem.javaType,
                                        "inoutType": listItem.inoutType,
                                        "param": listItem.param,
                                        "scope": listItem.scope
                                    })
                                })
                            }
                            autoInterfaces.push({
                                type: item.type,
                                info: info
                            });
                        })
                    }
                })
            }
        },
        //环节信息保存
        SET_ACTLIST: (state, data) => {
           let actList = state.bpmnJson.formData.actList;
        	//环节的表单数据保存到工作流对象中。=
     	   if(data.oldData != null){
     	      //修改原有数据
     		  actList[actList.findIndex(item => JSON.stringify(item) === JSON.stringify(data.oldData))] = cloneObj(data.newData)
     	     }else{
     	        //添加新数据
     	    	actList.push(cloneObj(data.newData));
     	     }

               // 如果id发生变化,要修改以他开头的线和以他结尾的线
            if ((!data.oldData || data.newData.id != data.oldData.id) && state.nodeInfo.businessObject) {
                const transList = state.bpmnJson.formData.transList;
                const modeling = state.bpmnModeler.get('modeling');
                const elementRegistry = state.bpmnModeler.get('elementRegistry');
                // 以他开头的线们
                if (state.nodeInfo.businessObject.outgoing) {
                    state.nodeInfo.businessObject.outgoing.forEach(item => {
                        const transListIndex = transList.findIndex(listItem => listItem.id === item.id);
                        if (transListIndex > -1) {
                            const idArr = item.id.split('_TR');
                            const TRIndex = idArr.length -  1;
                            const newId = data.newData.id + '_TR' + idArr[TRIndex];
                            // 更新vuex中线的id,from
                            transList[transListIndex].id = newId;
                            transList[transListIndex].from = data.newData.id;
                            // 更新线的id和source
                            modeling.updateProperties(elementRegistry.get(item.id),{
                                id: newId,
                                source: state.nodeInfo
                            });
                        }
                    })
                }

                // 以他结尾的线们
                if (state.nodeInfo.businessObject.incoming) {
                    state.nodeInfo.businessObject.incoming.forEach(item => {
                        const transListIndex = transList.findIndex(listItem => listItem.id === item.id);
                        if (transListIndex > -1) {
                            // 更新vuex中线的to
                            transList[transListIndex].to = data.newData.id;
                            // 更新线的target
                            modeling.updateProperties(elementRegistry.get(item.id), { target: state.nodeInfo });
                        }
                    })
                }
            }
        },
        //泳道信息保存participant
        SET_PARTICIPANT: (state, data) => {
        	let participant = state.bpmnJson.formData.participant;
        	//泳道数据保存到工作流对象中
        	if(data.oldData != null){
        		//修改原有数据
        		participant[participant.findIndex(item => JSON.stringify(item) === JSON.stringify(data.oldData))] = cloneObj(data.newData)
        	}else{
        		//添加新数据
        		participant.push(cloneObj(data.newData));
        	}
        },
      //迁移线信息保存transList
      SET_TRANSLIST: (state, data) => {
        	let transList = state.bpmnJson.formData.transList;
        	//迁移线数据保存到工作流对象中
        	if(data.oldData != null){
        		//修改原有数据
        		transList[transList.findIndex(item => JSON.stringify(item) === JSON.stringify(data.oldData))] = cloneObj(data.newData)
        	}else{
        		//添加新数据
        		transList.push(cloneObj(data.newData));
        	}
        },
        //环节删除
        DEL_ACTLIST: (state, data) => {
        	let transList = state.bpmnJson.formData.transList;
        	let actList = state.bpmnJson.formData.actList;
        	//环节删除
        	actList.splice(data.index,1);
        	//环节关联的线
        	// transList.forEach((item,index)=> {
        	// 	if(item.from == data.id || item.to == data.id){
        	// 		transList.splice(index,1);
        	// 	}
        	// })
        },
        //泳道删除
        DEL_PARTICIPANT: (state, data) => {
        	//data 泳道的id和数组索引
        	let participants = state.bpmnJson.formData.participant;
        	let transList = state.bpmnJson.formData.transList;
        	let actList = state.bpmnJson.formData.actList;
        	//根据索引删除泳道
        	participants.splice(data.index,1);
        	
        	actList.forEach((x,xindex)=> {
        		//环节所属泳道
        		if(x.performer == data.id){
        			//删除环节
        			actList.splice(xindex, 1);
        			//环节关联的线
        			// transList.forEach((y,yindex)=> {
        			// 	if(y.from == x.id || y.to == x.id){
        			// 		transList.splice(yindex,1);
        			// 	}
        			
        			// })
        		}
        	})
        },
        //迁移线信息删除
        DEL_TRANSLIST: (state, data) => {
            if (state.bpmnJson.formData.transList.length && state.bpmnJson.formData.transList.length > data) {
                const transId = state.bpmnJson.formData.transList[data].id
                if (transId) {
                    // 更新线之前环节的poin_lineCount和poin_cacheIndexs
                    deleteConnection(transId, state.bpmnModeler.get('elementRegistry'))
                }
            }
        	state.bpmnJson.formData.transList.splice(data,1);
        },
        // 删除环节的同时,删除其前后的线数据,actEL为环节图形对象
        DEL_ACT_TRANS: (state, actEl) => {
            if (!actEl) {
                return;
            }
            const elementRegistry = state.bpmnModeler.get('elementRegistry');
            if (actEl.incoming) {
                // 仅当该环节前后都只有一条线时,会删除其后线的数据,它之前的线的数据 (bpmn:SequenceFlow)更新
                if (actEl.incoming.length === 1 && actEl.outgoing && actEl.outgoing.length === 1 && 'bpmn:SequenceFlow' === actEl.incoming[0].type) {
                    const transIndex = state.bpmnJson.formData.transList.findIndex(titem => titem.id === actEl.incoming[0].id);
                    if (transIndex > -1) {
                        state.bpmnJson.formData.transList[transIndex].to = actEl.outgoing[0].target.id;
                    }
                } else {
                    // 其他情况,前面的线都应该删除,并更新线前面环节的poin_lineCount和poin_cacheIndexs
                    actEl.incoming.forEach(item => {
                        const transIndex = state.bpmnJson.formData.transList.findIndex(titem => titem.id === item.id)
                        if (transIndex > -1) {
                            state.bpmnJson.formData.transList.splice(transIndex ,1)
                        }
                        deleteConnection(item.id, elementRegistry)
                    });
                }
            }
            // 只要有后面的线,就应该删除,无需更新线前面环节的信息,因为已经被删除
            if (actEl.outgoing) {
                actEl.outgoing.forEach(item => {
                    const transIndex = state.bpmnJson.formData.transList.findIndex(titem => titem.id === item.id)
                    if (transIndex > -1) {
                        state.bpmnJson.formData.transList.splice(transIndex,1)
                    }
                });
            }
        },
        //任务流程保存数据
        SET_TASK_JSON: (state, info) => {
            state.taskJson = info
        },
        //保存任务流程 xml数据
        SET_TASK_XML:(state, data) => {
            state.taskJson.flowXmlData = data
        },
       //保存任务流程-[创建任务]环节flowNodeData
        SET_FLOWNODEDATA: (state, data) => {
        	let flowNodeData = state.taskJson.flowNodeData;
        	//flowNodeData数据保存到工作流对象中
        	if(data.oldData != null){
        		//修改原有数据
        		flowNodeData[flowNodeData.findIndex(item => JSON.stringify(item) === JSON.stringify(data.oldData))] = cloneObj(data.newData)
        	}else{
        		//添加新数据
        		flowNodeData.push(cloneObj(data.newData));
        	}
        },
        //保存任务基本信息数据
        SET_TASK_BASEDATA: (state, data) => {
            state.taskJson.unitFlag = data.unitFlag;
        	state.taskJson.flowId = data.flowId;
        	state.taskJson.jobGroup = data.jobGroup;
        	state.taskJson.flowDesc = data.flowDesc
        	state.taskJson.flowCron = data.flowCron
        	state.taskJson.addTime = data.addTime
        	state.taskJson.author = data.author
        	//增加字段add by 陆静2021-07-12
        	state.taskJson.fileCoordFlag = data.fileCoordFlag
        	state.taskJson.fileCron = data.fileCron
        	state.taskJson.filePath = data.filePath
        	state.taskJson.fileBean = data.fileBean
        	//增加字段add by 陆静2021-09-15
        	state.taskJson.alarmNumLimit = data.alarmNumLimit
        	state.taskJson.expectExecuteTimes = data.expectExecuteTimes
        	//黑名单字段add by ynj2021-12-02
        	state.taskJson.flowBlackDate = data.flowBlackDate
        	//add by myl 2021-12-1
        	state.taskJson.deadTime = data.deadTime
        	state.taskJson.temporaryFlag = data.temporaryFlag
        	//增加字段 by fyz 2022-4-12
        	state.taskJson.flowParam = data.flowParam
        },
       //删除任务环节数据
        DEL_NODEDATA:(state, data)=>{
          state.taskJson.flowNodeData.splice(data,1)
        }
        
    },
    actions: {

    }
}

export default bpmn