//using Hotline.Application.Contracts.Validators.FlowEngine; //using Hotline.Caching.Interfaces; //using Hotline.Caching.Services; //using Hotline.FlowEngine; //using Hotline.FlowEngine.Definitions; //using Hotline.FlowEngine.WorkflowModules; //using Hotline.FlowEngine.Workflows; //using Hotline.Identity.Accounts; //using Hotline.Identity.Roles; //using Hotline.Orders; //using Hotline.SeedData; //using Hotline.Settings; //using Hotline.Settings.TimeLimits; //using Hotline.Share.Dtos; //using Hotline.Share.Dtos.FlowEngine; //using Hotline.Share.Enums.FlowEngine; //using Hotline.Share.Enums.Identity; //using Hotline.Users; //using MapsterMapper; //using SqlSugar; //using XF.Domain.Authentications; //using XF.Domain.Dependency; //using XF.Domain.Entities; //using XF.Domain.Exceptions; //using XF.Domain.Repository; //namespace Hotline.Application.FlowEngine; //public class WorkflowApplication1 : IWorkflowApplication, IScopeDependency //{ // private readonly IDefinitionDomainService _definitionDomainService; // private readonly IWorkflowDomainService _workflowDomainService; // private readonly IOrderDomainService _orderDomainService; // private readonly IWorkflowRepository _workflowRepository; // private readonly IRepository _workflowAssignRepository; // private readonly IRepository _userRepository; // private readonly IAccountRepository _accountRepository; // private readonly ISystemOrganizeRepository _organizeRepository; // private readonly IRepository _roleRepository; // private readonly IWfModuleCacheManager _wfModuleCacheManager; // private readonly ISystemDomainService _systemDomainService; // private readonly IUserDomainService _userDomainService; // private readonly IAccountDomainService _accountDomainService; // private readonly ISessionContext _sessionContext; // private readonly IMapper _mapper; // public WorkflowApplication( // IDefinitionDomainService definitionDomainService, // IWorkflowDomainService workflowDomainService, // IOrderDomainService orderDomainService, // IWorkflowRepository workflowRepository, // IRepository workflowAssignRepository, // IRepository userRepository, // IAccountRepository accountRepository, // ISystemOrganizeRepository organizeRepository, // IRepository roleRepository, // IWfModuleCacheManager wfModuleCacheManager, // ISystemDomainService systemDomainService, // ISessionContext sessionContext, // IMapper mapper) // { // _definitionDomainService = definitionDomainService; // _workflowDomainService = workflowDomainService; // _orderDomainService = orderDomainService; // _workflowRepository = workflowRepository; // _workflowAssignRepository = workflowAssignRepository; // _userRepository = userRepository; // _accountRepository = accountRepository; // _organizeRepository = organizeRepository; // _roleRepository = roleRepository; // _wfModuleCacheManager = wfModuleCacheManager; // _systemDomainService = systemDomainService; // _sessionContext = sessionContext; // _mapper = mapper; // } // public async Task StartWorkflowAsync(StartWorkflowDto dto, string externalId, CancellationToken cancellationToken) // { // var validator = new StartWorkflowDtoValidator(); // var validResult = validator.Validate(dto); // if (!validResult.IsValid) // throw new UserFriendlyException($"非法参数, {string.Join(',', validResult.Errors.Select(d => d.ErrorMessage))}"); // var wfModule = await GetWorkflowModuleAsync(dto.DefinitionModuleCode, cancellationToken); // var definition = wfModule.Definition; // if (definition == null) // throw new UserFriendlyException("无效模板编码"); // if (definition.Status is not EDefinitionStatus.Enable) // throw new UserFriendlyException("该模板不可用"); // var nextStepBoxDefine = _workflowDomainService.GetStepBoxDefine(definition, dto.NextStepCode); // if (dto.IsStartCountersign && // (nextStepBoxDefine.StepType is EStepType.Summary || nextStepBoxDefine.CountersignMode is not ECountersignMode.Support)) // throw UserFriendlyException.SameMessage("下一节点不支持办理会签"); // //1. 如果不是按角色指派,handlers必填 2. 如果按角色指派,handlers可以不选 // if (nextStepBoxDefine.HandlerType is not EHandlerType.Role && !dto.NextHandlers.Any()) // throw UserFriendlyException.SameMessage("未指派办理人"); // var workflow = await _workflowDomainService.CreateWorkflowAsync(wfModule, dto.Title, // _sessionContext.RequiredUserId, _sessionContext.RequiredOrgId, externalId, cancellationToken); // var flowAssignMode = await GetFlowAssignModeAsync(nextStepBoxDefine, dto.IsStartCountersign, dto.NextHandlers, cancellationToken); // await _workflowDomainService.StartAsync(workflow, dto, nextStepBoxDefine, flowAssignMode, cancellationToken); // ////更新接办部门(详情页面展示) // //await AddOrUpdateAssignAsync(workflow, dto, nextStepBoxDefine, cancellationToken); // } // /// // /// 流转至下一节点(节点办理) // /// // public async Task NextAsync(NextWorkflowDto dto, CancellationToken cancellationToken) // { // var workflow = await _workflowDomainService.GetWorkflowAsync(dto.WorkflowId, true, true, withCountersigns: true, cancellationToken: cancellationToken); // //await NextAsync(workflow, dto, dto.ExpiredTime, dto.IsStartCountersign, cancellationToken); // //未超期工单,节点超期时间不能小于当前时间,不能大于流程整体超期时间 // if (workflow.ExpiredTime > DateTime.Now && (dto.ExpiredTime <= DateTime.Now || dto.ExpiredTime > workflow.ExpiredTime)) // throw UserFriendlyException.SameMessage("节点期满时间无效"); // var nextStepBoxDefine = _workflowDomainService.GetStepBoxDefine(workflow.WorkflowDefinition, dto.NextStepCode); // //需求:按角色选择办理人可以不选,表示该角色下所有人都可以办理,同时依据配置:是否本部门人办理显示待选办理人。角色下只要一人办理即可(即:角色下不发起会签) // if (nextStepBoxDefine.HandlerType != EHandlerType.Role && !dto.NextHandlers.Any()) // throw new UserFriendlyException("未指定节点处理者"); // if (dto.IsStartCountersign && // (nextStepBoxDefine.StepType is EStepType.Summary || nextStepBoxDefine.CountersignMode is not ECountersignMode.Support)) // throw UserFriendlyException.SameMessage("下一节点不支持办理会签"); // var flowAssignMode = await GetFlowAssignModeAsync(nextStepBoxDefine, dto.IsStartCountersign, dto.NextHandlers, cancellationToken); // await _workflowDomainService.NextAsync(workflow, dto, nextStepBoxDefine, flowAssignMode, dto.ExpiredTime, cancellationToken); // ////更新接办部门(详情页面展示) // //await AddOrUpdateAssignAsync(workflow, dto, nextStepBoxDefine, cancellationToken); // } // /// // /// 撤回至任意节点 // /// // public async Task RecallAsync(RecallDto dto, CancellationToken cancellationToken) // { // var workflow = await _workflowDomainService.GetWorkflowAsync(dto.WorkflowId, true, true, cancellationToken: cancellationToken); // await _orderDomainService.ReadyToRecallAsync(workflow.ExternalId, cancellationToken); // var targetStepDefine = _workflowDomainService.GetStepBoxDefine(workflow.WorkflowDefinition, dto.NextStepCode); // //var isStartCountersign = targetStepDefine.CouldPrevStartCountersign(dto.NextHandlers.Count); // var flowAssignMode = await GetFlowAssignModeAsync(targetStepDefine, dto.IsStartCountersign, dto.NextHandlers, cancellationToken); // await _workflowDomainService.RecallAsync(workflow, dto, targetStepDefine, flowAssignMode, cancellationToken); // } // /// // /// 跳转至任意节点 // /// // public async Task JumpAsync(RecallDto dto, CancellationToken cancellationToken) // { // var workflow = await _workflowDomainService.GetWorkflowAsync(dto.WorkflowId, true, true, cancellationToken: cancellationToken); // await _orderDomainService.ReadyToRecallAsync(workflow.ExternalId, cancellationToken); // var targetStepDefine = _workflowDomainService.GetStepBoxDefine(workflow.WorkflowDefinition, dto.NextStepCode); // //var isStartCountersign = targetStepDefine.CouldPrevStartCountersign(dto.NextHandlers.Count); // var flowAssignMode = await GetFlowAssignModeAsync(targetStepDefine, dto.IsStartCountersign, dto.NextHandlers, cancellationToken); // await _workflowDomainService.JumpAsync(workflow, dto, targetStepDefine, dto.IsStartCountersign, flowAssignMode, cancellationToken); // } // /// // /// 重办 // /// // public async Task RedoAsync(RecallDto dto, CancellationToken cancellationToken) // { // var workflow = await _workflowDomainService.GetWorkflowAsync(dto.WorkflowId, true, true, cancellationToken: cancellationToken); // var targetStepDefine = _workflowDomainService.GetStepBoxDefine(workflow.WorkflowDefinition, dto.NextStepCode); // var flowAssignInfo = await GetFlowAssignModeAsync(targetStepDefine, dto.IsStartCountersign, dto.NextHandlers, cancellationToken); // await _workflowDomainService.RedoAsync(workflow, dto, targetStepDefine, flowAssignInfo, cancellationToken); // } // public async Task GetStartOptionsAsync(string moduleCode, CancellationToken cancellationToken) // { // var wfModule = await GetWorkflowModuleAsync(moduleCode, cancellationToken); // var definition = wfModule.Definition; // if (definition == null) // throw new UserFriendlyException("无效模板编码"); // if (definition.Status is not EDefinitionStatus.Enable) // throw new UserFriendlyException("该模板不可用"); // var startStep = definition.Steps.FirstOrDefault(d => d.StepType == EStepType.Start); // if (startStep == null) // throw new UserFriendlyException("未正确配置开始节点"); // //var firstStepDefines = definition.FindStepDefines(startStep.NextSteps.Select(d => d.Code)); // var firstStepDefine = definition.FindStepDefine(startStep.NextSteps.First().Code); // if (firstStepDefine == null) // throw new UserFriendlyException("未正确配置首个办理节点"); // var secondStepDefines = definition.FindStepDefines(firstStepDefine.NextSteps.Select(d => d.Code)); // if (firstStepDefine.PathPolicy is not EPathPolicy.None && firstStepDefine.NextSteps.Count > 1) // _workflowDomainService.NextStepDefineFilter(firstStepDefine.PathPolicy, secondStepDefines); // return new DefinedStepDto // { // DefinitionId = definition.Id, // Steps = _mapper.Map>(secondStepDefines),//secondStepDefines.Select(d => new KeyValuePair(d.Code, d.Name)).ToList() // Components = firstStepDefine.Components // }; // } // /// // /// 根据节点配置查询待选参数 // /// // /// // /// // /// // /// // public async Task GetNextStepOptionsAsync(StepDefine stepDefine, CancellationToken cancellationToken) // { // if (stepDefine.StepType == EStepType.End) return new(); // var handlers = new List(); // switch (stepDefine.HandlerType) // { // case EHandlerType.AssignedUser: // var users = await _userRepository.QueryAsync(d => // !d.IsDeleted && // stepDefine.HandlerTypeItems.Select(d => d.Key).Contains(d.Id)); // handlers = users.Select(d => new Kv(d.Id, d.Name)).ToList(); // break; // case EHandlerType.AssignedOrg: // var orgs = await _organizeRepository.QueryAsync(d => // d.IsEnable && // stepDefine.HandlerTypeItems.Select(d => d.Key).Contains(d.Id)); // handlers = orgs.Select(d => new Kv(d.Id, d.Name)) // .ToList(); // break; // case EHandlerType.Role: // var roles = await _roleRepository.Queryable() // .Includes(d => d.Accounts.Where(x => !x.IsDeleted && x.Status == EAccountStatus.Normal).ToList(), x => x.User) // .Where(d => stepDefine.HandlerTypeItems.Select(d => d.Key).Contains(d.Name)) // .ToListAsync(cancellationToken); // var users1 = roles.SelectMany(d => d.Accounts).Select(d => d.User); // handlers = users1.Select(d => new Kv(d.Id, d.Name)).ToList(); // break; // case EHandlerType.OrgLevel: // //当前操作人所属部门的下级部门并且属于配置orgLevel的部门 // var levels = stepDefine.HandlerTypeItems.Select(d => d.Key).Select(d => int.Parse(d)); // var levelOneOrg = _sessionContext.RequiredOrgId.GetHigherOrgCode(); // //var orgs1 = await _organizeRepository.QueryAsync(d => // // d.IsEnable && d.OrgCode.StartsWith(levelOneOrg) && // // levels.Contains(d.OrgLevel)); // var orgs1 = await _organizeRepository.Queryable() // .Where(d => d.IsEnable && levels.Contains(d.Level)) // .WhereIF(!levelOneOrg.IsCenter(), d => d.Id.StartsWith(levelOneOrg)) // .ToListAsync(cancellationToken); // handlers = orgs1.Select(d => new Kv(d.Id, d.Name)).ToList(); // break; // case EHandlerType.OrgType: // var types = stepDefine.HandlerTypeItems.Select(d => d.Key) // .Select(d => Enum.Parse(d)); // var levelOneOrg1 = _sessionContext.RequiredOrgId.GetHigherOrgCode(); // //var org2 = await _organizeRepository.QueryAsync(d => // // d.IsEnable && d.OrgCode.StartsWith(levelOneOrg1) && // // types.Contains(d.OrgType)); // var orgs2 = await _organizeRepository.Queryable() // .Where(d => d.IsEnable && types.Contains(d.OrgType)) // .WhereIF(!levelOneOrg1.IsCenter(), d => d.Id.StartsWith(levelOneOrg1)) // .ToListAsync(cancellationToken); // handlers = orgs2.Select(d => new Kv(d.Id, d.Name)).ToList(); // break; // default: // throw new ArgumentOutOfRangeException(); // } // var dto = new NextStepOptionDto { Handlers = handlers }; // if (stepDefine.Components.Contains(SysDicTypeConsts.OrderRedoReason)) // { // var orderRedoReasons = await _systemDomainService.GetSysDicDataByCodeAsync(SysDicTypeConsts.OrderRedoReason, cancellationToken); // dto.OrderRedoReasonOptions = orderRedoReasons.Select(d => new Kv(d.DicDataValue, d.DicDataName)).ToList(); // } // return dto; // } // /// // /// 查询指派办理人的处理方式及实际办理人 // /// // public async Task GetFlowAssignModeAsync(StepDefine stepDefine, bool isStartCountersign, List handlers, CancellationToken cancellationToken) // { // if (stepDefine.StepType is EStepType.Start or EStepType.End) return new(); // switch (stepDefine.HandlerType) // { // case EHandlerType.Role: // if (!handlers.Any()) // { // var roles = await _roleRepository.Queryable() // .Includes(d => d.Accounts, x => x.User) // .Where(d => stepDefine.HandlerTypeItems.Select(d => d.Key).Contains(d.Name)) // .ToListAsync(cancellationToken); // handlers = roles.SelectMany(d => d.Accounts).Distinct().Select(d => new Kv(d.Id, d.User.Name)).ToList(); // } // return FlowAssignInfo.Create(EFlowAssignType.User, handlers, isStartCountersign); // case EHandlerType.OrgLevel: // case EHandlerType.OrgType: // case EHandlerType.AssignedOrg: // return FlowAssignInfo.Create(EFlowAssignType.Org, handlers, isStartCountersign); // case EHandlerType.AssignedUser: // return FlowAssignInfo.Create(EFlowAssignType.User, handlers, isStartCountersign); // default: // throw new ArgumentOutOfRangeException(); // } // } // #region private // /// // /// 查询流程业务模块 // /// // /// // /// // /// // private async Task GetWorkflowModuleAsync(string code, CancellationToken cancellationToken) // { // var wfModule = await _wfModuleCacheManager.GetWorkflowModuleAsync(code, cancellationToken); // if (wfModule == null) // throw UserFriendlyException.SameMessage("无效流程模块编码"); // if (wfModule.Definition is null) // throw new UserFriendlyException($"{code} 未配置流程模板", "未配置流程模板"); // return wfModule; // } // /// // /// 更新接办部门 // /// // private async Task AddOrUpdateAssignAsync(Workflow workflow, BasicWorkflowDto dto, StepDefine nextStepBoxDefine, CancellationToken cancellationToken) // { // if (nextStepBoxDefine.StepType is EStepType.Normal) // { // await _workflowAssignRepository.RemoveAsync(d => // d.WorkflowId == workflow.Id && d.OrgCode == _sessionContext.RequiredOrgId, // cancellationToken: cancellationToken); // var assigns = new List(); // switch (nextStepBoxDefine.HandlerType) // { // case EHandlerType.Role: // if (dto.NextHandlers.Any()) // { // //选了handler,handler为userId // var users1 = await _userRepository.Queryable() // .Includes(d => d.Organization) // .Where(d => dto.NextHandlers.Select(x => x.Key).Contains(d.Id)) // .ToListAsync(cancellationToken); // assigns = users1.Select(d => WorkflowAssign.Create(workflow.Id, d.Id, d.Organization.Name)) // .ToList(); // } // else // { // ////如果模板配置为本部门办理,则为当前办理人orgCode,非本部门办理:属于该角色的所有用户所属部门 // //if (nextStepBoxDefine.OnlySelfOrg.HasValue && nextStepBoxDefine.OnlySelfOrg.Value) // //{ // // assigns = new List // // { // // WorkflowAssign.Create(workflow.Id, _sessionContext.RequiredOrgCode, _sessionContext.OrgName) // // }; // //} // //else // //{ // var accounts = await _accountRepository.Queryable() // .Includes(d => d.User, d => d.Organization) // .Where(d => dto.NextHandlers.Select(d => d.Key).Contains(d.Name)) // .ToListAsync(cancellationToken); // assigns = accounts.Select(d => d.User.Organization).Select(d => // WorkflowAssign.Create(workflow.Id, d.Id, d.Name)).ToList(); // //} // } // break; // case EHandlerType.OrgLevel: // case EHandlerType.OrgType: // case EHandlerType.AssignedOrg: // assigns = dto.NextHandlers.Select(d => WorkflowAssign.Create(workflow.Id, d.Key, d.Value)).ToList(); // break; // case EHandlerType.AssignedUser: // //指定人所属部门 // var users = await _userRepository.Queryable() // .Includes(d => d.Organization) // .Where(d => dto.NextHandlers.Select(x => x.Key).Contains(d.Id)) // .ToListAsync(cancellationToken); // assigns = users.Select(d => WorkflowAssign.Create(workflow.Id, d.Id, d.Organization.Name)) // .ToList(); // break; // default: // throw new ArgumentOutOfRangeException(); // } // if (assigns.Any()) // await _workflowAssignRepository.AddRangeAsync(assigns, cancellationToken); // } // } // #endregion //}