private static void addFlowInstanceFriendlyLog( FlowInstance flowInstance, int flowActionRequestId, string currentActivityName, int paticipantUserId, int?delegateeUserId, string actionName, string paticipantMemo, EnouFlowInstanceContext db) { var log = db.flowFriendlyLogs.Create(); log.FlowInstance = flowInstance; log.flowActionRequestId = flowActionRequestId; log.currentActivityName = currentActivityName; using (var orgDb = new EnouFlowOrgMgmtContext()) { UserHelper userHelper = new UserHelper(orgDb); var paticipant = userHelper.getUserDTO(paticipantUserId); log.paticipantName = paticipant.name + (paticipant.englishName == null ? "" : "/" + paticipant.englishName); if (delegateeUserId.HasValue) { var delegatee = userHelper.getUserDTO(delegateeUserId.Value); log.delegateeName = delegatee.name + (delegatee.englishName == null ? "" : "/" + delegatee.englishName); } } log.actionName = actionName; log.paticipantMemo = paticipantMemo; db.flowFriendlyLogs.Add(log); }
private void updateTaskForUserStatesAfterAction(EnouFlowInstanceContext db, int actionUserId, DateTime bizTimeStamp, DateTime newBizTimeStamp, string currentActivityGuid, FlowInstance flowInst, FlowActionRequest reqInDb) { var tasks = db.flowTaskForUsers.Where(t => t.FlowInstance.flowInstanceId == flowInst.flowInstanceId && t.bizTimeStamp == bizTimeStamp && t.currentActivityGuid == currentActivityGuid).ToList(); tasks.ForEach(t => { if (t.userId != actionUserId) { // 其他用户已删除该任务或是已完成的邀请提供处理意见的任务,不需要标记为过期 if (t.taskState != EnumFlowTaskState.deletedByUser && t.taskState != EnumFlowTaskState.done) { t.taskState = EnumFlowTaskState.obsoleted; } } else { t.finishTime = newBizTimeStamp; t.taskState = EnumFlowTaskState.done; t.FlowActionRequest = reqInDb; t.delegateeUserId = reqInDb.delegateeUserId; // 有可能是被任务代理人完成 t.delegateeUserGuid = reqInDb.delegateeUserGuid; } }); //db.SaveChanges(); }
private FlowInstance getFlowInstance(EnouFlowInstanceContext db, int flowInstanceId, string bizDocumentGuid) { FlowInstance flowInst = db.flowInstances.Find(flowInstanceId); if (flowInst == null) { flowInst = db.flowInstances.Where( inst => inst.bizDocumentGuid == bizDocumentGuid) .ToList().FirstOrDefault(); } return(flowInst); }
private FlowTaskForUser addFlowTaskForUser(EnouFlowInstanceContext db, UserDTO user, FlowInstance flowInst, EnumFlowTaskType taskType = EnumFlowTaskType.normal) { var task = db.flowTaskForUsers.Create(); task.userId = user.userId; task.userGuid = user.guid; task.FlowInstance = flowInst; task.bizDocumentGuid = flowInst.bizDocumentGuid; task.bizDocumentTypeCode = flowInst.bizDocumentTypeCode; task.bizTimeStamp = flowInst.bizTimeStamp; task.currentActivityGuid = flowInst.currentActivityGuid; task.taskType = taskType; db.flowTaskForUsers.Add(task); return(task); }
public FlowActionStartResult // start processActionRequest(FlowActionStart req) { using (var db = new EnouFlowInstanceContext()) { string failReason; var reqInDb = getReqInDB(req.flowActionRequestId, db); var flowInst = db.flowInstances.Create(); flowInst.flowTemplateId = req.concreteMetaObj.flowTemplateId; flowInst.flowTemplateJson = FlowTemplateDBHelper.getFlowTemplate( flowInst.flowTemplateId).flowTemplateJson; var flowDefHelper = new FlowTemplateDefHelper( flowInst.flowTemplateJson); flowInst.creatorId = req.concreteMetaObj.userId; flowInst.code = req.concreteMetaObj.code; flowInst.processingState = EnumFlowInstanceProcessingState. waitingActionRequest; flowInst.lifeState = EnumFlowInstanceLifeState.start; // 此处TimeStamp不能直接取Now, 因为启动流程时会几乎同时生成两个 // ActionRequest, 否则第二个ActionRequest的bizTimeStamp就会马上过期 flowInst.bizTimeStamp = flowInst.mgmtTimeStamp = req.createTime; flowInst.currentActivityGuid = req.concreteMetaObj.currentActivityGuid; flowInst.currentActivityName = flowDefHelper.getNodeFromGuid( flowInst.currentActivityGuid).name; flowInst.startActivityGuid = flowInst.currentActivityGuid; flowInst.bizDataPayloadJson = req.bizDataPayloadJson; flowInst.bizDocumentGuid = req.bizDocumentGuid; flowInst.bizDocumentTypeCode = req.bizDocumentTypeCode; db.flowInstances.Add(flowInst); #region 如果需要, 则Add FlowTaskForUser List <UserDTO> taskUsers = new List <UserDTO>(); if (req.needGenerateTaskForUser) { taskUsers = getUserDTOsFromPaticipantList(req.roles, flowInst); if (taskUsers.Count() == 0) // 如果参与活动的用户数为0则出错 { failReason = $"无法找到参与活动'{flowInst.currentActivityName}'" + $"的用户({req.roles.ToString()})."; updateReqProcessingResultInDB(reqInDb, EnumFlowActionRequestResultType.fail, failReason); db.SaveChanges(); return(new FlowActionStartResult(req.flowActionRequestId, req.clientRequestGuid, flowInst, false, failReason)); } } #endregion // 新建的流程需要回填对应的处理请求对象关于流程实例的信息, // 由下面updateRequestToSuccess完成 #region update request updateRequestToSuccess(reqInDb, flowInst); #endregion #warning TODO: Add FlowInstanceFriendlyLog & FlowInstanceTechLog addFlowInstanceFriendlyLog( flowInst, reqInDb.flowActionRequestId, flowInst.previousActivityName, reqInDb.userId.Value, reqInDb.delegateeUserId, "提交(开始)/Submit(Start)", req.userMemo, db); db.SaveChanges(); return(new FlowActionStartResult( req.flowActionRequestId, req.clientRequestGuid, flowInst)); } }
public FlowActionMoveToAutoGeneratedResult // moveToAutoGenerated processActionRequest(FlowActionMoveToAutoGenerated req) { var concreteMetaObj = req.concreteMetaObj; using (var db = new EnouFlowInstanceContext()) { var flowInst = getFlowInstance(db, req.flowInstanceId, req.bizDocumentGuid); var reqInDb = getReqInDB(req.flowActionRequestId, db); Tuple <ActivityNode, ActivityNode, ActivityConnection> from_to_conn; string failReason; #region Check BizTimeStamp Valid 自动型跳过检查 //if (!isBizTimeStampValid((DateTime)concreteMetaObj.bizTimeStamp, // req, flowInst, db, out failReason)) //{ // updateReqProcessingResultInDB(reqInDb, // EnumFlowActionRequestResultType.fail, failReason); // db.SaveChanges(); // return new FlowActionMoveToAutoGeneratedResult(req.flowActionRequestId, // req.clientRequestGuid, flowInst, false, failReason); //} #endregion #region Decide next activity, switch different activity type var flowDefHelper = new FlowTemplateDefHelper( flowInst.flowTemplateJson); from_to_conn = flowDefHelper.getNodesOfConnection(req.connectionGuid); #region 验证流程实例当前所处的状态能够使用该connection if (from_to_conn.Item1.guid != flowInst.currentActivityGuid) { failReason = $"当前所处的状态{from_to_conn.Item1.name}" + $"不支持使用连接{from_to_conn.Item3.name}"; updateReqProcessingResultInDB(reqInDb, EnumFlowActionRequestResultType.fail, failReason); db.SaveChanges(); return(new FlowActionMoveToAutoGeneratedResult(req.flowActionRequestId, req.clientRequestGuid, flowInst, false, failReason)); } #endregion #endregion #region 目的状态是自动类型时需要根据条件为该活动自动生成接续的对应FlowActionRequest if (from_to_conn.Item2.type == ActivityTypeString.standard_Auto) { var _toActivity = from_to_conn.Item2; // 目标自动活动 var _autoResult = ExecuteAutoRulesAsync(_toActivity.autoRules, req.bizDataPayloadJson, req.optionalFlowActionDataJson, flowInst).Result; var _effectiveConnectionGuid = _autoResult.Item1; var _paticipantsOfAutoRules = _autoResult.Item2; //根据自动活动规则集的运行结果由引擎Post相应的MoveToAutoGenerated型处理请求 FlowActionHelper.PostFlowActionMoveToAutoGenerated( Guid.NewGuid().ToString(), req.bizDocumentGuid, req.bizDocumentTypeCode, DateTime.Now, "自动活动规则生成", req.bizDataPayloadJson, req.optionalFlowActionDataJson, flowInst.flowInstanceId, flowInst.guid, flowInst.code, from_to_conn.Item2.guid, _effectiveConnectionGuid, flowDefHelper.getNodesOfConnection( _effectiveConnectionGuid).Item2.guid, _paticipantsOfAutoRules, db); } #endregion #region Decide activity owners/ List<UserDTO> List <UserDTO> taskUsers = new List <UserDTO>(); switch (from_to_conn.Item2.type) { case ActivityTypeString.standard_End: // 目标活动状态为结束,不需要设置activity owner, 是否需要有最终收尾处理的人 ??? break; case ActivityTypeString.standard_Start: // 下面这三类目标活动状态需要设置activity owner case ActivityTypeString.standard_SingleHuman: case ActivityTypeString.standard_MultiHuman: // taskUsers = FlowTemplateDefHelper.getUserDTOsFromPaticipantList(req.roles); taskUsers = getUserDTOsFromPaticipantList(req.roles, flowInst); if (taskUsers.Count() == 0) // 如果参与活动的用户数为0则出错 { failReason = $"无法找到参与活动'{from_to_conn.Item2.name}'" + $"的用户({req.roles.ToString()})."; updateReqProcessingResultInDB(reqInDb, EnumFlowActionRequestResultType.fail, failReason); db.SaveChanges(); return(new FlowActionMoveToAutoGeneratedResult(req.flowActionRequestId, req.clientRequestGuid, flowInst, false, failReason)); } break; case ActivityTypeString.standard_Auto: // 目标活动状态为自动,暂定不设置activity owner break; default: throw new EnouFlowInstanceLib.DataLogicException( $"遇到未定义处理方式的活动类型: {from_to_conn.Item2.type}"); } #endregion #region update instance switch (from_to_conn.Item2.type) { case ActivityTypeString.standard_End: flowInst.lifeState = EnumFlowInstanceLifeState.end; break; case ActivityTypeString.standard_Start: flowInst.lifeState = EnumFlowInstanceLifeState.start; break; case ActivityTypeString.standard_SingleHuman: case ActivityTypeString.standard_MultiHuman: case ActivityTypeString.standard_Auto: flowInst.lifeState = EnumFlowInstanceLifeState.middle; break; default: throw new EnouFlowInstanceLib.DataLogicException( $"遇到未定义处理方式的活动类型: {from_to_conn.Item2.type}"); } flowInst.bizTimeStamp = DateTime.Now; flowInst.currentActivityGuid = from_to_conn.Item2.guid; flowInst.currentActivityName = from_to_conn.Item2.name; flowInst.previousActivityGuid = from_to_conn.Item1.guid; flowInst.previousActivityName = from_to_conn.Item1.name; updateBizDataPayloadJsonOfFlowInst(flowInst, req); #endregion #region Create request automatically for auto activity #endregion #region update tasks for user status like taskState,finishTime //自动型不需要做该动作,因为FromNode是自动型,应该无人工任务产生 #endregion #region add task for users: FlowTaskForUser taskUsers.ForEach(user => addFlowTaskForUser(db, user, flowInst)); #endregion #region write 3 type logs: FlowInstanceFriendlyLog & FlowInstanceTechLog #endregion #region update request updateRequestToSuccess(reqInDb, flowInst); #endregion #region save all to db db.SaveChanges(); #endregion return(new FlowActionMoveToAutoGeneratedResult(req.flowActionRequestId, req.clientRequestGuid, flowInst)); } }
public FlowActionTerminateResult // teminate processActionRequest(FlowActionTerminate req) { var concreteMetaObj = req.concreteMetaObj; using (var db = new EnouFlowInstanceContext()) { var flowInst = getFlowInstance(db, req.flowInstanceId, req.bizDocumentGuid); var reqInDb = getReqInDB(req.flowActionRequestId, db); string failReason; DateTime bizTimeStampToUse = DateTime.Now; var flowDefHelper = new FlowTemplateDefHelper( flowInst.flowTemplateJson); var toActivity = flowDefHelper.getNodeFromGuid(req.nextActivityGuid); var currentActivity = flowDefHelper.getNodeFromGuid(req.currentActivityGuid); #region update instance switch (toActivity.type) { case ActivityTypeString.standard_End: flowInst.lifeState = EnumFlowInstanceLifeState.terminated; break; default: throw new EnouFlowInstanceLib.DataLogicException( $"不能终止到非停止状态的活动类型: {toActivity.type}"); } var originBizTimeStamp = flowInst.bizTimeStamp; flowInst.bizTimeStamp = bizTimeStampToUse; flowInst.currentActivityGuid = toActivity.guid; flowInst.currentActivityName = toActivity.name; flowInst.previousActivityGuid = currentActivity.guid; flowInst.previousActivityName = currentActivity.name; #endregion #region update tasks for user status like taskState,finishTime updateTaskForUserStatesAfterAction(db, (int)concreteMetaObj.userId, originBizTimeStamp, bizTimeStampToUse, flowInst.previousActivityGuid, flowInst, reqInDb); #endregion #region write 3 type logs: FlowInstanceFriendlyLog & FlowInstanceTechLog addFlowInstanceFriendlyLog( flowInst, reqInDb.flowActionRequestId, flowInst.previousActivityName, reqInDb.userId.Value, reqInDb.delegateeUserId, "终止/Terminate", req.userMemo, db); #warning TODO: another 2 type logs #endregion #region update request updateRequestToSuccess(reqInDb, flowInst); #endregion #region save all to db db.SaveChanges(); #endregion return(new FlowActionTerminateResult(req.flowActionRequestId, req.clientRequestGuid, flowInst)); } }
public void Setup() { db = new EnouFlowInstanceContext(); }
public FlowActionInviteOtherResult // inviteOther = More approval processActionRequest(FlowActionInviteOther req) { var concreteMetaObj = req.concreteMetaObj; using (var db = new EnouFlowInstanceContext()) { var flowInst = getFlowInstance(db, req.flowInstanceId, req.bizDocumentGuid); var reqInDb = getReqInDB(req.flowActionRequestId, db); string failReason; // 此类型ActionRequest不改TimeStamp DateTime bizTimeStampToUse = flowInst.bizTimeStamp; #region Check BizTimeStamp Valid if (!isBizTimeStampValid((DateTime)concreteMetaObj.bizTimeStamp, req, flowInst, out failReason)) { updateReqProcessingResultInDB(reqInDb, EnumFlowActionRequestResultType.fail, failReason); db.SaveChanges(); return(new FlowActionInviteOtherResult(req.flowActionRequestId, req.clientRequestGuid, flowInst, false, failReason)); } #endregion #region Decide List<UserDTO> //use the parameters of request List <UserDTO> taskUsers = new List <UserDTO>(); // taskUsers = FlowTemplateDefHelper.getUserDTOsFromPaticipantList(req.roles); taskUsers = getUserDTOsFromPaticipantList(req.roles, flowInst); #endregion #region add the invitation task for users: FlowTaskForUser taskUsers.ForEach(user => { var task = addFlowTaskForUser( db, user, flowInst, EnumFlowTaskType.invitation); // 邀请他人提供意见需要设置本身任务的FlowTaskForUserId用于对应跟踪 task.relativeFlowTaskForUserId = req.relativeFlowTaskForUserId; }); #endregion #region write 3 type logs addFlowInstanceFriendlyLog( flowInst, reqInDb.flowActionRequestId, flowInst.currentActivityName, reqInDb.userId.Value, reqInDb.delegateeUserId, "征询意见/Invite opinion", req.userMemo, db); #warning TODO: another 2 type logs #endregion #region update request updateRequestToSuccess(reqInDb, flowInst); #endregion #region save all to db db.SaveChanges(); #endregion return(new FlowActionInviteOtherResult(req.flowActionRequestId, req.clientRequestGuid, flowInst)); } }
private FlowActionRequest getReqInDB(int id, EnouFlowInstanceContext db) { return(db.flowActionRequests.Find(id)); }
processActionRequest(FlowActionInviteOtherFeedback req) { var concreteMetaObj = req.concreteMetaObj; using (var db = new EnouFlowInstanceContext()) { var flowInst = getFlowInstance(db, req.flowInstanceId, req.bizDocumentGuid); var reqInDb = getReqInDB(req.flowActionRequestId, db); string failReason; // 此类型ActionRequest不改TimeStamp DateTime bizTimeStampToUse = flowInst.bizTimeStamp; #region Check BizTimeStamp Valid if (!isBizTimeStampValid((DateTime)concreteMetaObj.bizTimeStamp, req, flowInst, out failReason)) { updateReqProcessingResultInDB(reqInDb, EnumFlowActionRequestResultType.fail, failReason); db.SaveChanges(); return(new FlowActionInviteOtherFeedbackResult(req.flowActionRequestId, req.clientRequestGuid, flowInst, false, failReason)); } #endregion #region Decide List<UserDTO> // 需要追溯到最初发出征询意见的用户作为任务目标用户 List <UserDTO> taskUsers = new List <UserDTO>(); var taskInviteOther = db.flowTaskForUsers.Find( req.relativeFlowTaskForUserId); var flowTaskForUserOrigin = db.flowTaskForUsers.Find( taskInviteOther.relativeFlowTaskForUserId); using (var orgDb = new EnouFlowOrgMgmtContext()) { taskUsers.Add( new UserHelper(orgDb).getUserDTO( flowTaskForUserOrigin.userId)); } #endregion #region add the invitation-feedback "task" for users FlowTemplateDefHelper flowTemplateDefHelper = new FlowTemplateDefHelper(flowInst.flowTemplateJson); string suggestedConnectionName = ""; if (!string.IsNullOrWhiteSpace(req.connectionGuid)) { suggestedConnectionName = flowTemplateDefHelper.getNodesOfConnection( req.connectionGuid).Item3.name; } string suggestedPaticipants = ""; if (req.roles.Count() > 0) { suggestedPaticipants = req.roles.Aggregate( "", (names, role) => { if (role != null) { return(names + role.PaticipantObj.name + ";"); } else { return(names); } }); } taskUsers.ForEach(user => { var task = addFlowTaskForUser( db, user, flowInst, EnumFlowTaskType.invitationFeedback); // 设置任务之间的跟踪关系 task.relativeFlowTaskForUserId = req.relativeFlowTaskForUserId; // 设置征询意见反馈型任务的自定义字段 task.stringField_1 = req.userMemo; task.stringField_2 = suggestedConnectionName; task.stringField_3 = suggestedPaticipants; }); // 顺便把原征询意见的任务也一并更新 taskInviteOther.stringField_1 = req.userMemo; taskInviteOther.stringField_2 = suggestedConnectionName; taskInviteOther.stringField_3 = suggestedPaticipants; taskInviteOther.finishTime = DateTime.Now; taskInviteOther.taskState = EnumFlowTaskState.done; #endregion #region write 3 type logs addFlowInstanceFriendlyLog( flowInst, reqInDb.flowActionRequestId, flowInst.currentActivityName, reqInDb.userId.Value, reqInDb.delegateeUserId, "意见征询答复/Opinions invited", req.userMemo, db); #warning TODO: another 2 type logs #endregion #region update request updateRequestToSuccess(reqInDb, flowInst); #endregion #region save all to db db.SaveChanges(); #endregion return(new FlowActionInviteOtherFeedbackResult(req.flowActionRequestId, req.clientRequestGuid, flowInst)); } }
static void Main(string[] args) { bool testCreateOrgStru = false; bool testQueryOrgStru = false; bool testCreateSystemManager = false; bool testImportFlowDefinitionJSON = false; bool testCreateFlowTemplate = false; // Actions bool testCreateFlowActionStart = false; bool testCreateFlowActionMoveTo_1 = false; bool testCreateFlowActionMoveTo_2 = false; bool testCreateFlowActionMoveTo_3 = false; bool testCreateFlowActionMoveTo_4 = false; bool testCreateFlowActionRejectToStart = false; bool testCreateFlowActionJumpTo_1 = false; //bool testCreateFlowActionTake = false; //bool testCreateFlowActionInviteOther = false; //bool testCreateFlowActionFeedBackOfInvite = false; // Engine bool testRunEngine = false; // OPAS2Model bool testBizDocumentSerialNoGenerator = false; bool testCreatePR = false; bool testGenerateBizDataPayloadJson = false; // FlowDynamicUser bool testFlowDynamicUser = false; #region Test OrgMgmtLib #region Creation if (testCreateOrgStru) { using (var db = new EnouFlowOrgMgmtContext()) { // var DBHelper = DBHelper; var orgHelper = new OrgHelper(db); var _org = orgHelper.createObject(); _org.name = "CQAC集团"; orgHelper.saveCreatedObject(_org); var orgSchemaHelper = new OrgSchemaHelper(db); var _orgSchema = orgSchemaHelper.createObject(); _orgSchema.name = "默认组织结构方案"; _orgSchema.Org = _org; orgSchemaHelper.saveCreatedObject(_orgSchema); var bizEntityHelper = new BizEntityHelper(db); var _bizEntity = bizEntityHelper.createObject(); _bizEntity.name = "Qoros汽车有限公司"; bizEntityHelper.saveCreatedObject(_orgSchema, _bizEntity, null); //var _bizEntityChild = OrgMgmtDBHelper.createBizEntity(db); //_bizEntityChild.name = "上海总部"; //OrgMgmtDBHelper.saveCreatedBizEntity(_orgSchema, _bizEntityChild, _bizEntity, db); //var _bizEntityChild2 = OrgMgmtDBHelper.createBizEntity(db); //_bizEntityChild2.name = "常熟生产基地"; //OrgMgmtDBHelper.saveCreatedBizEntity(_orgSchema, _bizEntityChild2, _bizEntity, db); BizEntitySchemaHelper bizEntitySchemaHelper = new BizEntitySchemaHelper(db); var _bizEntitySchema = bizEntitySchemaHelper.createObject(); _bizEntitySchema.name = "Qoros默认公司架构"; _bizEntitySchema.BizEntity = _bizEntity; bizEntitySchemaHelper.saveCreatedObject(_bizEntitySchema); DepartmentHelper departmentHelper = new DepartmentHelper(db); var _department0 = departmentHelper.createObject(); _department0.name = "董事会"; departmentHelper.saveCreatedObject(_bizEntitySchema, _department0, null); //var _department = departmentHelper.createObject() ; //_department.name = "后台部门"; //OrgMgmtDBHelper.saveCreatedDepartment(_bizEntitySchema, _department, null, db); var _department1 = departmentHelper.createObject(); _department1.name = "产品部"; departmentHelper.saveCreatedObject(_bizEntitySchema, _department1, null); var _departmentChild = departmentHelper.createObject(); _departmentChild.name = "财务部"; departmentHelper.saveCreatedObject(_bizEntitySchema, _departmentChild, null); UserHelper userHelper = new UserHelper(db); var _user = userHelper.createObject(); _user.name = "张三"; userHelper.saveCreatedObject(_user); var _user2 = userHelper.createObject(); _user2.name = "李四"; userHelper.saveCreatedObject(_user2); var _user3 = userHelper.createObject(); _user3.name = "王五"; userHelper.saveCreatedObject(_user3); userHelper.createDepartmentUserRelation(_departmentChild, _user); userHelper.createDepartmentUserRelation(_departmentChild, _user2); userHelper.createDepartmentUserRelation(_department1, _user3); RoleHelper roleHelper = new RoleHelper(db); var _role = roleHelper.createObject(); _role.name = "系统管理员"; roleHelper.saveCreatedObject(_role); var _role1 = roleHelper.createObject(); _role1.name = "CXOs"; roleHelper.saveCreatedObject(_role1); userHelper.setUserRole(_user.userId, _role); userHelper.setUserRole(_user.userId, _role1); userHelper.setUserRole(_user2.userId, _role1); RoleTypeHelper roleTypeHelper = new RoleTypeHelper(db); RoleType _roleType = roleTypeHelper.createObject(); _roleType.name = "系统"; roleTypeHelper.saveCreatedObject(_roleType); roleHelper.createRole_RoleTypeRelation(_role, _roleType); } } #endregion #region Query if (testQueryOrgStru) { using (var db = new EnouFlowOrgMgmtContext()) { //找到一个OrgSchema下的顶级业务实体集 var defaultOrg = db.orgs.ToList().FirstOrDefault(); if (defaultOrg == null) { Console.WriteLine("No defaultOrg Exists."); Console.Read(); return; } var defaultOrgSchema = defaultOrg.orgSchema; if (defaultOrgSchema == null) { Console.WriteLine("No defaultOrgSchema Exists."); Console.Read(); return; } var rootBizEntities = defaultOrg.orgSchema.rootBizEntities; var rootBizEntity = rootBizEntities[0]; if (rootBizEntity == null) { Console.WriteLine("No rootBizEntity Exists."); Console.Read(); return; } //找到一个业务实体指定OrgSchema的下级业务实体集 var bizEntityChildren = rootBizEntity.getBizEntitiesChildren( db, db.orgs.ToList().FirstOrDefault().orgSchema); var bizEntityChild = bizEntityChildren[0]; //找到一个业务实体指定OrgSchema的上级业务实体 var bizEntityParent = bizEntityChild.getBizEntitiyParent( db, db.orgs.ToList().FirstOrDefault().orgSchema); //找到一个业务实体指定BizEntitySchema下的顶级部门集 var depts = bizEntityChild.bizEntitySchemas[0].getRootDepartments(db); //找到一个部门的所有下级部门 var dps = depts.LastOrDefault().getDepartmentChildren(db); //找到一个部门的上级部门 var dp1 = depts.LastOrDefault().getDepartmentChildren(db)[1]; var dpParent = dp1.getParentDepartment(db); dpParent = dpParent.getParentDepartment(db); //找到一个部门的所有用户 var usrs = dp1.getUserChildren(db); //找到一个用户的所有部门 var u = usrs[0]; var depts1 = u.getDepartmentsBelongTo(db); //找到一个用户的所有角色 var roles = u.getRolesBelongTo(db); //找到一个角色的所有用户 var cxos = db.roles.ToList()[1].getUsersBelongTo(db); Console.WriteLine("查询完成."); //return; } } #endregion #endregion #region Test OrgMgmtLib.SystemManager if (testCreateSystemManager) { using (var db = new EnouFlowOrgMgmtContext()) { //if (db.systemManagers.Count() <= 0) //{ // var _sysmgr = db.systemManagers.Create(); // _sysmgr.name = "系统管理员"; // _sysmgr.logonName = "sys"; // _sysmgr.logonSalt = "f6152039-1745-4f4c-8f8e-3ed37770fa0d"; // _sysmgr.logonPasswordHash = Convert.ToBase64String( // new System.Security.Cryptography.SHA256Managed().ComputeHash( // Encoding.UTF8.GetBytes( // "111111" + //测试密码 // "f6152039-1745-4f4c-8f8e-3ed37770fa0d"))); // db.systemManagers.Add(_sysmgr); // db.SaveChanges(); // Console.WriteLine("成功创建系统管理员"); //} } } #endregion var PRFlowTemplateFilePath = @"C:\data\MyProjs\99Flow\EnouFlow\internal\test_flow.json"; var POFlowTemplateFilePath = @"C:\data\MyProjs\99Flow\EnouFlow\EnouFlowEngine\PO.json"; var GRFlowTemplateFilePath = @"C:\data\MyProjs\99Flow\EnouFlow\EnouFlowEngine\GR.json"; var PMFlowTemplateFilePath = @"C:\data\MyProjs\99Flow\EnouFlow\EnouFlowEngine\PM.json"; #region Test import Flow Definition JSON if (testImportFlowDefinitionJSON) { StreamReader oJsonFile = new StreamReader( POFlowTemplateFilePath); //StreamReader oJsonFile = new System.IO.StreamReader( //@"C:\data\MyProjs\99Flow\EnouFlow\EnouFlowEngine\test_flow.json"); var flowTemplateDefTest = JsonHelper.DeserializeJsonToObject <FlowTemplateDef>( oJsonFile.ReadToEnd()); dynamic temp = parseJsonToDynamicObject("{'AmountTotal': 49999}"); Console.WriteLine("成功导入流程定义文件"); } #endregion #region Test Create Flow Template in DB if (testCreateFlowTemplate) { StreamReader oJsonFile = new StreamReader(PMFlowTemplateFilePath); var tplJson = oJsonFile.ReadToEnd(); var flowTemplateDefTest = JsonHelper.DeserializeJsonToObject <FlowTemplateDef>( tplJson); Tuple <bool, FlowTemplate, List <string> > result = FlowTemplateDBHelper.createFlowTemplate( flowTemplateDefTest.basicInfo.guid, flowTemplateDefTest.basicInfo.name, flowTemplateDefTest.basicInfo.displayName, flowTemplateDefTest.basicInfo.version, "PM", tplJson ); var tpl = result.Item2; //tpl.guid = flowTemplateDefTest.basicInfo.guid; //tpl.name = flowTemplateDefTest.basicInfo.name; //tpl.displayName = flowTemplateDefTest.basicInfo.displayName; //tpl.version = flowTemplateDefTest.basicInfo.version; //tpl.code = "PM"; //tpl.flowTemplateJson = tplJson; FlowTemplateDBHelper.saveCreatedFlowTemplate(tpl); Console.WriteLine("成功创建流程定义模板"); } #endregion #region Test Create FlowActions #region Test Create FlowActionStart if (testCreateFlowActionStart) { var actionStart = FlowActionHelper.PostFlowActionStart( "aaaaaaa-1745-4f4c-8f8e-3ed37770fa0d", "bizDocumentGuid", "PR", "用户输入的备注内容aaa", null, null, 1, "abc", 1, "def", null, "TestFlow-001", "f6152039-1745-4f4c-8f8e-3ed37770fa0d" ); } #endregion #region Test Create FlowActionMoveTo if (testCreateFlowActionMoveTo_1) { var action1 = FlowActionHelper.PostFlowActionMoveTo( "bbbbbbb-1745-4f4c-8f8e-3ed37770fa0d", "bizDocumentGuid", "PR", DateTime.Now.AddSeconds(1), "用户输入的备注内容bbb", "{'AmountTotal': 50001}", "{'AmountTotalUpdated': 49999}", 1, "user-guid", 0, null, "TestFlow-001", "f6152039-1745-4f4c-8f8e-3ed37770fa0d", "9d985ac5-a1da-4c63-8aea-83e9974ffccc", "9d4a6006-1099-46ad-b037-24e84476ab50", new List <Paticipant>() { new Paticipant("user", new PaticipantDigest( "李四", "27bcd361-12c7-4376-8dd8-ce68ad964431", 2, null, null) ) }, null, null ); } if (testCreateFlowActionMoveTo_2) { var action2 = FlowActionHelper.PostFlowActionMoveTo( "cccccc-1745-4f4c-8f8e-3ed37770fa0d", "bizDocumentGuid", "PR", DateTime.Now.AddSeconds(2), "用户输入的备注内容ccc", null, null, 1, "user-guid", 1, "flow-inst-guid", "TestFlow-001", "2dde0ed2-c10b-4c98-b263-1016dcfa951d", "55d72a3e-051a-46a0-9aae-0be1c62b2e24", "ab0f92f6-35cd-44b9-a7bd-5a17e544aa9c", new List <Paticipant>() { new Paticipant("user", new PaticipantDigest( "王五", "f17004ea-1246-40df-9f48-2adf0cfa8517", 3, null, null) ) }, null, null ); } if (testCreateFlowActionMoveTo_3) { var action3 = FlowActionHelper.PostFlowActionMoveTo( "dddddd-1745-4f4c-8f8e-3ed37770fa0d", "bizDocumentGuid", "PR", DateTime.Now.AddSeconds(3), "用户输入的备注内容ddd", null, null, 1, "user-guid", 1, "flow-inst-guid", "TestFlow-001", "ab0f92f6-35cd-44b9-a7bd-5a17e544aa9c", "ceeae036-7b21-438f-bc46-33bfad0cc546", "5ee19a5b-df8b-4c11-a0d4-082848b5f216", new List <Paticipant>() { new Paticipant("user", new PaticipantDigest( "张三", "85a14f4d-e68e-4684-88b2-3bf9dea386e6", 1, null, null) ) }, null, null ); } if (testCreateFlowActionMoveTo_4) { var action4 = FlowActionHelper.PostFlowActionMoveTo( "eeeeee-1745-4f4c-8f8e-3ed37770fa0d", "bizDocumentGuid", "PR", DateTime.Now.AddSeconds(4), "用户输入的备注内容eee", null, null, 1, "user-guid", 1, "flow-inst-guid", "TestFlow-001", "5ee19a5b-df8b-4c11-a0d4-082848b5f216", "0dade9b8-acc9-4223-8dab-9d55480722a8", "c09fcfbe-92a9-48cd-bd14-975996e063a7", new List <Paticipant>(), null, null //{ // new Paticipant("user", // new PaticipantDigest( // "川普", // "c4961686-41a6-469a-afa9-df05e42ba9f8", // 16,null) // ) //} ); } #endregion #region TODO: Test Create FlowActionTake #endregion #region TODO: Test Create FlowActionInviteOther #endregion #region TODO: Test Create FlowActionFeedBackOfInvite #endregion #endregion #region Test Engine if (testRunEngine) { var dispatcher = new FlowActionRequestDispatcher(); //EnumFlowActionRequestType[] types = new EnumFlowActionRequestType[] { EnumFlowActionRequestType.moveToAutoGenerated }; //dispatcher.processNextActionOfSpecifiedInstance(1, types); var result = dispatcher.processNextAction(); } #endregion #region Test BizDocumentSerialNoGenerator if (testBizDocumentSerialNoGenerator) { var prNumberNew = new OPAS2ModelDBHelper(). generateDocumentSerialNo(EnumBizDocumentType.PR, "QOROS", "SH", "2017", "IT"); Console.WriteLine(prNumberNew); } #endregion #region Test CreatePR if (testCreatePR) { var prNumberNew = new OPAS2ModelDBHelper(). generateDocumentSerialNo(EnumBizDocumentType.PR, "QOROS", "SH", "2017", "IT"); Console.WriteLine(prNumberNew); using (var db = new OPAS2DbContext()) { var pr = db.purchaseReqs.Create(); pr.guid = "test-pr-guid:" + Guid.NewGuid().ToString(); pr.documentNo = new OPAS2ModelDBHelper().generateDocumentSerialNo( EnumBizDocumentType.PR, "QOROS", "SH", "2017", "IT"); pr.WBSNo = "test-WBS"; pr.contactOfficePhone = "contactOfficePhone"; pr.contactMobile = "contactMobile"; pr.contactOtherMedia = "contactOtherMedia"; pr.departmentId = 1; pr.departmentIdBelongTo = 1; pr.costCenterId = 1; pr.expectReceiveBeginTime = DateTime.Now; pr.expectReceiveEndTime = DateTime.Now; pr.isBidingRequired = true; pr.noBiddingReason = "noBiddingReason"; pr.reason = "reason"; pr.description = "description"; pr.estimatedCost = (decimal)123456.789; pr.currencyTypeId = 1; pr.mainCurrencyRate = (decimal)1.0; pr.estimatedCostInRMB = (decimal)123456.789; pr.averageBenchmark = (decimal)787654.78; pr.benchmarkDescription = "benchmarkDescription"; pr.isFirstBuy = false; pr.firstBuyDate = DateTime.Now; pr.firstCostAmount = (decimal)73663387.87; pr.firstBuyDescription = "firstBuyDescription"; pr.remarkOfAprrovers = "remarkOfAprrovers"; pr.otherVendorsNotInList = "otherVendorsNotInList"; pr.submitTime = DateTime.Now; pr.submitor = "ChaoQin"; pr.submitorUserId = 1; pr.creator = "ChaoQin"; pr.creatorUserId = 1; var prDtl1 = db.purchaseReqDetails.Create(); prDtl1.PurchaseReq = pr; prDtl1.estimatedCost = (decimal)123.45; prDtl1.lineNo = 5; prDtl1.itemName = "name1"; prDtl1.itemType = (EnumPRItemType)1; prDtl1.description = "description1"; prDtl1.creator = "ChaoQin"; prDtl1.creatorUserId = 1; //pr.details.Add(prDtl1); db.purchaseReqs.Add(pr); db.purchaseReqDetails.Add(prDtl1); db.SaveChanges(); Console.WriteLine("PR: " + pr.purchaseReqId.ToString()); } } #endregion #region Test GenerateBizDataPayloadJson if (testGenerateBizDataPayloadJson) { using (var db = new OPAS2DbContext()) { var pr = db.purchaseReqs.Find(8); dynamic bizDataPayload = new ExpandoObject(); bizDataPayload.document = pr; //bizDataPayload.subDocuments = pr.details; bizDataPayload.AmountTotal = pr.details.Aggregate <PurchaseReqDetail, decimal>( 0, (total, detail) => { return(total + detail.estimatedCost.Value); }); var s = JsonConvert.SerializeObject(bizDataPayload, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, } ); Console.WriteLine(s); } } #endregion #region testFlowDynamicUser Console.Out.WriteLine("Enter into script:"); var _session = new DictionaryContext(); var flowInstDb = new EnouFlowInstanceContext(); var flowInstance = FlowInstanceHelper.GetFlowInstance(42, flowInstDb); _session.globals.Add("flowInstance", flowInstance); var _references = new Assembly[] { typeof(DictionaryContext).Assembly, typeof(System.Runtime.CompilerServices.DynamicAttribute).Assembly, typeof(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo).Assembly, typeof(ExpandoObject).Assembly, typeof(JsonConvert).Assembly, typeof(ExpandoObjectConverter).Assembly, typeof(Paticipant).Assembly, typeof(UserDTO).Assembly, typeof(FlowInstance).Assembly, typeof(List <>).Assembly }; var _imports = new string[] { typeof(DictionaryContext).Namespace, typeof(System.Runtime.CompilerServices.DynamicAttribute).Namespace, typeof(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo).Namespace, typeof(ExpandoObject).Namespace, typeof(JsonConvert).Namespace, typeof(ExpandoObjectConverter).Namespace, typeof(Paticipant).Namespace, typeof(UserDTO).Namespace, typeof(FlowInstance).Namespace, typeof(List <>).Namespace }; var _options = ScriptOptions.Default .AddReferences(_references) .AddImports(_imports); //var code = @"var result = new List<UserDTO>(); // result.Add(OrgMgmtDBHelper.getUserDTO(((FlowInstance)globals[""flowInstance""]).creatorId)); // return result;"; using (var db = new EnouFlowOrgMgmtContext()) { var retShouldBe = new DepartmentHelper(db).getUserDTOsOfPositionInDepartment( new UserHelper(db).getUserDefaultDepartment(flowInstance.creatorId).departmentId, UserPositionToDepartment.manager); } var code = @" FlowInstance flowInstance = (FlowInstance)globals[""flowInstance""]; Department department = OrgMgmtDBHelper.getUserDefaultDepartment(flowInstance.creatorId); if(department!=null){ return OrgMgmtDBHelper.getUserDTOsOfPositionInDepartment( department.departmentId, UserPositionToDepartment.manager); }else{ return null; }"; var result1 = CSharpScript.RunAsync(code, globals: _session, options: _options).Result.ReturnValue; var retList = (List <UserDTO>)result1; #endregion Console.WriteLine("All done!"); Console.Read(); }
public FlowActionJumpToResult // jumpTo processActionRequest(FlowActionJumpTo req) { var concreteMetaObj = req.concreteMetaObj; using (var db = new EnouFlowInstanceContext()) { var flowInst = getFlowInstance(db, req.flowInstanceId, req.bizDocumentGuid); var reqInDb = getReqInDB(req.flowActionRequestId, db); string failReason; DateTime bizTimeStampToUse = DateTime.Now; #region Check BizTimeStamp Valid if (!req.forceJump && !isBizTimeStampValid( (DateTime)concreteMetaObj.bizTimeStamp, req, flowInst, out failReason)) { updateReqProcessingResultInDB(reqInDb, EnumFlowActionRequestResultType.fail, failReason); db.SaveChanges(); return(new FlowActionJumpToResult(req.flowActionRequestId, req.clientRequestGuid, flowInst, false, failReason)); } #endregion var flowDefHelper = new FlowTemplateDefHelper( flowInst.flowTemplateJson); var toActivity = flowDefHelper.getNodeFromGuid(req.nextActivityGuid); var currentActivity = flowDefHelper.getNodeFromGuid(req.currentActivityGuid); #region 目的状态是自动类型时需要根据条件为该活动自动生成接续的对应FlowActionRequest if (toActivity.type == ActivityTypeString.standard_Auto) { //var _toActivity = toActivity; // 目标自动活动 var _autoResult = ExecuteAutoRulesAsync(toActivity.autoRules, req.bizDataPayloadJson, req.optionalFlowActionDataJson, flowInst).Result; var _effectiveConnectionGuid = _autoResult.Item1; var _paticipantsOfAutoRules = _autoResult.Item2; // 根据自动活动规则集的运行结果由引擎Post相应的MoveToAutoGenerated型处理请求 // 但不马上处理,由客户端或者流程引擎后台调度器自动调用处理 FlowActionHelper.PostFlowActionMoveToAutoGenerated( Guid.NewGuid().ToString(), req.bizDocumentGuid, req.bizDocumentTypeCode, DateTime.Now, "自动活动规则生成", req.bizDataPayloadJson, req.optionalFlowActionDataJson, flowInst.flowInstanceId, flowInst.guid, flowInst.code, toActivity.guid, _effectiveConnectionGuid, flowDefHelper.getNodesOfConnection(_effectiveConnectionGuid).Item2.guid, _paticipantsOfAutoRules, db); } #endregion #region Decide activity owners/ List<UserDTO> List <UserDTO> taskUsers = new List <UserDTO>(); switch (toActivity.type) { case ActivityTypeString.standard_End: // 目标活动状态为结束,不需要设置activity owner, 是否需要有最终收尾处理的人 ??? break; case ActivityTypeString.standard_Start: // 下面这三类目标活动状态需要设置activity owner case ActivityTypeString.standard_SingleHuman: case ActivityTypeString.standard_MultiHuman: // taskUsers = FlowTemplateDefHelper.getUserDTOsFromPaticipantList(req.roles); taskUsers = getUserDTOsFromPaticipantList(req.roles, flowInst); if (taskUsers.Count() == 0) // 如果参与活动的用户数为0则出错 { failReason = $"无法找到参与活动'{toActivity.name}'" + $"的用户({req.roles.ToString()})."; updateReqProcessingResultInDB(reqInDb, EnumFlowActionRequestResultType.fail, failReason); db.SaveChanges(); return(new FlowActionJumpToResult(req.flowActionRequestId, req.clientRequestGuid, flowInst, false, failReason)); } break; case ActivityTypeString.standard_Auto: // 目标活动状态为自动,暂定不设置activity owner break; default: throw new EnouFlowInstanceLib.DataLogicException( $"遇到未定义处理方式的活动类型: {toActivity.type}"); } #endregion #region update instance switch (toActivity.type) { case ActivityTypeString.standard_End: flowInst.lifeState = EnumFlowInstanceLifeState.end; break; case ActivityTypeString.standard_Start: flowInst.lifeState = EnumFlowInstanceLifeState.start; break; case ActivityTypeString.standard_SingleHuman: case ActivityTypeString.standard_MultiHuman: case ActivityTypeString.standard_Auto: flowInst.lifeState = EnumFlowInstanceLifeState.middle; break; default: throw new EnouFlowInstanceLib.DataLogicException( $"遇到未定义处理方式的活动类型: {toActivity.type}"); } var originBizTimeStamp = flowInst.bizTimeStamp; flowInst.bizTimeStamp = bizTimeStampToUse; flowInst.currentActivityGuid = toActivity.guid; flowInst.currentActivityName = toActivity.name; flowInst.previousActivityGuid = currentActivity.guid; flowInst.previousActivityName = currentActivity.name; updateBizDataPayloadJsonOfFlowInst(flowInst, req); #endregion #region update tasks for user status like taskState,finishTime updateTaskForUserStatesAfterAction(db, (int)concreteMetaObj.userId, originBizTimeStamp, bizTimeStampToUse, flowInst.previousActivityGuid, flowInst, reqInDb); #endregion #region add task for users: FlowTaskForUser taskUsers.ForEach(user => addFlowTaskForUser(db, user, flowInst)); #endregion #region write 3 type logs: FlowInstanceFriendlyLog & FlowInstanceTechLog addFlowInstanceFriendlyLog( flowInst, reqInDb.flowActionRequestId, flowInst.previousActivityName, reqInDb.userId.Value, reqInDb.delegateeUserId, "跳转/Jump", req.userMemo, db); #warning TODO: another 2 type logs #endregion #region update request updateRequestToSuccess(reqInDb, flowInst); #endregion #region save all to db db.SaveChanges(); #endregion return(new FlowActionJumpToResult(req.flowActionRequestId, req.clientRequestGuid, flowInst)); } }
public FlowActionRejectToStartResult // rejectToStart processActionRequest(FlowActionRejectToStart req) { var concreteMetaObj = req.concreteMetaObj; using (var db = new EnouFlowInstanceContext()) { var flowInst = getFlowInstance(db, req.flowInstanceId, req.bizDocumentGuid); var reqInDb = getReqInDB(req.flowActionRequestId, db); string failReason; ActivityNode destNode; #region Check BizTimeStamp Valid if (!isBizTimeStampValid((DateTime)concreteMetaObj.bizTimeStamp, req, flowInst, out failReason)) { updateReqProcessingResultInDB(reqInDb, EnumFlowActionRequestResultType.fail, failReason); db.SaveChanges(); return(new FlowActionRejectToStartResult(req.flowActionRequestId, req.clientRequestGuid, flowInst, false, failReason)); } #endregion #region Decide next activity, need be start type var flowDefHelper = new FlowTemplateDefHelper( flowInst.flowTemplateJson); string startActivityGuid; if (string.IsNullOrWhiteSpace(req.startActivityGuid)) { startActivityGuid = flowInst.startActivityGuid; } else { startActivityGuid = req.startActivityGuid; } destNode = flowDefHelper.getNodeFromGuid(startActivityGuid); if (destNode.type != ActivityTypeString.standard_Start) { failReason = "目标活动不是开始类型(FlowActionRejectToStartResult)"; updateReqProcessingResultInDB(reqInDb, EnumFlowActionRequestResultType.fail, failReason); db.SaveChanges(); return(new FlowActionRejectToStartResult(req.flowActionRequestId, req.clientRequestGuid, flowInst, false, failReason)); } #endregion #region Decide activity owners/ List<UserDTO> List <UserDTO> taskUsers = new List <UserDTO>(); // taskUsers = FlowTemplateDefHelper.getUserDTOsFromPaticipantList(req.roles); taskUsers = getUserDTOsFromPaticipantList(req.roles, flowInst); if (taskUsers.Count() == 0) {// 如果没有直接指定用户, 则根据流程实例的creatorId,将任务指派给流程实例的创建者 using (var orgDb = new EnouFlowOrgMgmtContext()) { var creator = new UserHelper(orgDb).getUserDTO(flowInst.creatorId); if (creator != null) { taskUsers.Add(creator); } } } if (taskUsers.Count() == 0) // 如果参与活动的用户数为0则出错 { failReason = $@"无法找到参与活动'{destNode.name}'的用户" + $@"({ req.roles.ToString()}). (FlowActionRejectToStartResult)"; updateReqProcessingResultInDB(reqInDb, EnumFlowActionRequestResultType.fail, failReason); db.SaveChanges(); return(new FlowActionRejectToStartResult(req.flowActionRequestId, req.clientRequestGuid, flowInst, false, failReason)); } #endregion #region update instance DateTime newBizTimeStamp = DateTime.Now; DateTime originBizTimeStamp = flowInst.bizTimeStamp; flowInst.bizTimeStamp = newBizTimeStamp; flowInst.previousActivityGuid = flowInst.currentActivityGuid; flowInst.previousActivityName = flowInst.currentActivityName; flowInst.currentActivityGuid = destNode.guid; flowInst.currentActivityName = destNode.name; // RejectToStart不更新BizDataPayloadJson: // updateBizDataPayloadJsonOfFlowInst(flowInst, req); #endregion #region update tasks for user status like taskState,finishTime, delegatee updateTaskForUserStatesAfterAction(db, (int)concreteMetaObj.userId, originBizTimeStamp, newBizTimeStamp, flowInst.previousActivityGuid, flowInst, reqInDb); #endregion #region add task for users: FlowTaskForUser taskUsers.ForEach(user => addFlowTaskForUser(db, user, flowInst, EnumFlowTaskType.redraft)); #endregion #region write 3 type logs: FlowInstanceFriendlyLog & FlowInstanceTechLog addFlowInstanceFriendlyLog( flowInst, reqInDb.flowActionRequestId, flowInst.previousActivityName, reqInDb.userId.Value, reqInDb.delegateeUserId, "退回(拒绝)/Reject", req.userMemo, db); #warning TODO: another 2 type logs #endregion #region update request updateRequestToSuccess(reqInDb, flowInst); #endregion db.SaveChanges(); return(new FlowActionRejectToStartResult(req.flowActionRequestId, req.clientRequestGuid, flowInst)); } }