فهرست منبع

fixed: 结束会签无限压栈

xf 1 سال پیش
والد
کامیت
cc23bfaeec

+ 0 - 1508
src/Hotline/FlowEngine/Workflows/WorkflowDomainService1.cs

@@ -1,1508 +0,0 @@
-//using Hotline.FlowEngine.Definitions;
-//using Hotline.FlowEngine.Notifications;
-//using Hotline.FlowEngine.WorkflowModules;
-//using Hotline.Settings;
-//using Hotline.Share.Dtos;
-//using Hotline.Share.Dtos.FlowEngine;
-//using Hotline.Share.Enums.FlowEngine;
-//using MapsterMapper;
-//using MediatR;
-//using Microsoft.Extensions.Logging;
-//using XF.Domain.Authentications;
-//using XF.Domain.Dependency;
-//using XF.Domain.Exceptions;
-//using XF.Domain.Repository;
-
-//namespace Hotline.FlowEngine.Workflows
-//{
-//    public class WorkflowDomainService1 : IWorkflowDomainService, IScopeDependency
-//    {
-//        private readonly IWorkflowRepository _workflowRepository;
-//        private readonly IRepository<WorkflowStep> _workflowStepRepository;
-//        private readonly IRepository<WorkflowTrace> _workflowTraceRepository;
-//        private readonly IRepository<WorkflowAssign> _workflowAssignRepository;
-//        private readonly IRepository<WorkflowSupplement> _workflowSupplementRepository;
-//        private readonly IRepository<WorkflowCountersign> _workflowCountersignRepository;
-//        private readonly ISessionContext _sessionContext;
-//        private readonly IMapper _mapper;
-//        private readonly IMediator _mediator;
-//        private readonly ILogger<WorkflowDomainService> _logger;
-
-//        public WorkflowDomainService(
-//            IWorkflowRepository workflowRepository,
-//            IRepository<WorkflowStep> workflowStepRepository,
-//            IRepository<WorkflowTrace> workflowTraceRepository,
-//            IRepository<WorkflowAssign> workflowAssignRepository,
-//            IRepository<WorkflowSupplement> workflowSupplementRepository,
-//            IRepository<WorkflowCountersign> workflowCountersignRepository,
-//            ISessionContext sessionContext,
-//            IMapper mapper,
-//            IMediator mediator,
-//            ILogger<WorkflowDomainService> logger)
-//        {
-//            _workflowRepository = workflowRepository;
-//            _workflowStepRepository = workflowStepRepository;
-//            _workflowTraceRepository = workflowTraceRepository;
-//            _workflowAssignRepository = workflowAssignRepository;
-//            _workflowSupplementRepository = workflowSupplementRepository;
-//            _workflowCountersignRepository = workflowCountersignRepository;
-
-//            _sessionContext = sessionContext;
-//            _mapper = mapper;
-//            _mediator = mediator;
-//            _logger = logger;
-//        }
-
-//        public async Task<Workflow> CreateWorkflowAsync(WorkflowModule wfModule, string title, string userId, string userCode,
-//            string? externalId = null, CancellationToken cancellationToken = default)
-//        {
-//            var definition = wfModule.Definition;
-//            if (definition is null)
-//                throw new UserFriendlyException("无效流程模板");
-//            var workflow = new Workflow
-//            {
-//                Title = title,
-//                ModuleId = wfModule.Id,
-//                ModuleName = wfModule.Name,
-//                ModuleCode = wfModule.Code,
-//                DefinitionId = definition.Id,
-//                Status = EWorkflowStatus.Runnable,
-//                TimeLimit = GetTimeLimit(definition.Code),//todo 过期时间
-//                ExpiredTime = CalculateExpiredTime(definition.Code),//todo 过期时间
-//                Steps = new(),
-//                Traces = new(),
-//                WorkflowDefinition = definition,
-//                CenterToOrgTime = DateTime.Now,
-//                ExternalId = externalId ?? string.Empty,
-//                FlowedOrgIds = new List<string> { userCode },
-//                FlowedUserIds = new List<string> { userId },
-//            };
-
-//            await _workflowRepository.AddAsync(workflow, cancellationToken);
-
-//            return workflow;
-//        }
-
-//        /// <summary>
-//        /// 流程开始
-//        /// </summary>
-//        /// <param name="workflow"></param>
-//        /// <param name="dto"></param>
-//        /// <param name="cancellationToken"></param>
-//        /// <returns></returns>
-//        public async Task StartAsync(Workflow workflow, BasicWorkflowDto dto, StepDefine nextStepBoxDefine,
-//             FlowAssignInfo flowAssignInfo, CancellationToken cancellationToken)
-//        {
-//            //创建开始节点
-//            var (startStepBox, startStep, firstStepBox) = await CreateStartAndFirstStepAsync(workflow, dto, cancellationToken);
-
-//            //1.创建开始节点trace 2.创建firstStep(开始节点的下一个节点),办理firstStep 3.创建sec节点
-//            //办理firstStep
-//            var firstStep = firstStepBox.Steps.First();
-//            var counterSignType = GetCounterSignType(firstStep.BusinessType);
-
-//            await HandleStepAsync(workflow, dto, firstStepBox, firstStep, counterSignType, cancellationToken);
-
-//            await _workflowStepRepository.UpdateRangeAsync(new List<WorkflowStep> { firstStepBox, firstStep }, cancellationToken);
-
-//            //firstStep trace
-//            await NextTraceAsync(workflow, dto, firstStep, cancellationToken);
-
-//            //secondStep
-//            var secondStepDefine = workflow.WorkflowDefinition.FindStepDefine(dto.NextStepCode);
-//            var secondStepBox = await CreateStepAsync(workflow, secondStepDefine, dto,
-//                EWorkflowStepStatus.Created, firstStepBox, firstStep, EWorkflowTraceStatus.Normal,
-//                workflow.ExpiredTime, cancellationToken);
-
-//            //更新实际办理节点信息
-//            workflow.UpdateWorkflowActualHandleInfo(firstStepBox, firstStep,
-//                _sessionContext.RequiredUserId, _sessionContext.UserName,
-//                 _sessionContext.RequiredOrgId, _sessionContext.OrgName,
-//                _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName);
-
-//            //todo 计算办理工作时长
-
-//            //更新当前办理节点信息
-//            workflow.UpdateWorkflowCurrentStepInfo(dto.IsStartCountersign, firstStep, secondStepBox.Steps.First());
-
-//            //发起会签时记录顶层会签节点(必须在update currentStep之后)
-//            if (dto.IsStartCountersign && !workflow.IsInCountersign())
-//                workflow.StartCountersign(firstStepBox.Code, counterSignType);
-
-//            //更新受理人信息
-//            workflow.UpdateAcceptor(
-//                _sessionContext.RequiredUserId,
-//                _sessionContext.UserName,
-//                _sessionContext.StaffNo,
-//                _sessionContext.RequiredOrgId,
-//                _sessionContext.OrgName);
-
-//            workflow.UpdateHandlers(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId,
-//            flowAssignInfo.FlowAssignType, flowAssignInfo.HandlerObjects);
-
-//            //更新指派信息
-//            workflow.Assign(flowAssignInfo.FlowAssignType, flowAssignInfo.GetHandlerIds());
-
-//            await _workflowRepository.UpdateAsync(workflow, cancellationToken);
-
-//            //publish
-//            await _mediator.Publish(new StartWorkflowNotify(workflow, dto, flowAssignInfo), cancellationToken);
-
-//        }
-
-//        public async Task<Workflow> GetWorkflowAsync(string workflowId,
-//            bool withDefine = false, bool withSteps = false,
-//            bool withTraces = false, bool withSupplements = false,
-//            bool withAssigns = false, bool withCountersigns = false,
-//            CancellationToken cancellationToken = default)
-//        {
-//            var query = _workflowRepository.Queryable().Where(d => d.Id == workflowId);
-//            if (withDefine)
-//                query = query.Includes(d => d.WorkflowDefinition);
-//            if (withSupplements)
-//                query = query.Includes(d => d.Supplements, d => d.Creator);
-//            //if (withAssigns)
-//            //    query = query.Includes(d => d.Assigns);
-//            if (withCountersigns)
-//                query = query.Includes(d => d.Countersigns);
-
-//            var workflow = await query.FirstAsync();
-//            if (workflow is null)
-//                throw new UserFriendlyException("无效workflowId");
-
-//            if (withSteps)
-//            {
-//                var steps = await _workflowStepRepository.Queryable()
-//                    .Where(d => d.WorkflowId == workflow.Id)
-//                    .OrderBy(d => d.CreationTime)
-//                    .ToTreeAsync(d => d.Steps, d => d.ParentId, null);
-//                workflow.Steps = steps;
-//            }
-
-//            if (withTraces)
-//            {
-//                var traces = await _workflowTraceRepository.Queryable()
-//                    .Where(d => d.WorkflowId == workflow.Id)
-//                    .OrderBy(d => d.CreationTime)
-//                    .ToTreeAsync(d => d.Traces, d => d.ParentId, null);
-//                workflow.Traces = traces;
-//            }
-
-
-//            return workflow;
-//        }
-
-//        /// <summary>
-//        /// 查询工作流包含当前用户办理权限(是否可办理)
-//        /// </summary>
-//        public async Task<(Workflow, bool)> GetWorkflowHandlePermissionAsync(string workflowId, string userId, string orgCode, bool withDefine = false,
-//            bool withSteps = false, bool withTraces = false, bool withSupplements = false, bool withAssigns = false,
-//            bool withCountersigns = false, CancellationToken cancellationToken = default)
-//        {
-//            var workflow = await GetWorkflowAsync(workflowId, withDefine, withSteps, withTraces, withSupplements, withAssigns, withCountersigns, cancellationToken);
-//            var canHandle = workflow.CanHandle(userId, orgCode);
-//            return (workflow, canHandle);
-//        }
-
-//        /// <summary>
-//        /// 受理(接办)
-//        /// </summary>
-//        public async Task AcceptAsync(Workflow workflow, string userId, string userName, string orgCode, string orgName, CancellationToken cancellationToken)
-//        {
-//            if (!workflow.CanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId)) return;
-//            //工单完成以后查看的场景
-//            if (workflow.Status != EWorkflowStatus.Runnable) return;
-
-//            var (currentStepBox, currentStep) = GetUnCompleteStepOrDefault(workflow.Steps, orgCode, userId);
-//            if (currentStep is null) return;
-//            if (currentStep.Status is EWorkflowStepStatus.WaitForHandle) return;
-//            if (currentStep.HandlerType is EHandlerType.AssignedUser or EHandlerType.Role)
-//            {
-//                //userId
-//                if (currentStep.Handlers.All(d => d.Key != userId)) return;
-//            }
-//            else
-//            {
-//                //orgId
-//                if (currentStep.Handlers.All(d => d.Key != orgCode)) return;
-//            }
-//            if (currentStep.StepType is EStepType.End)
-//                throw new UserFriendlyException("当前流程已流转到最终步骤");
-
-//            var changedSteps = new List<WorkflowStep> { currentStep };
-//            if (currentStepBox.Status is EWorkflowStepStatus.WaitForAccept)
-//            {
-//                currentStepBox.Status = EWorkflowStepStatus.WaitForHandle;
-//                changedSteps.Add(currentStepBox);
-//            }
-//            currentStep.Accept(userId, userName, _sessionContext.RequiredOrgId, _sessionContext.OrgName);
-
-//            //接办时非会签并且有多个接办部门时需更新接办部门
-//            if (!workflow.IsInCountersign())
-//            {
-//                var assigns = await _workflowAssignRepository.QueryAsync(d => d.WorkflowId == workflow.Id);
-//                if (assigns.Count > 1)
-//                {
-//                    await _workflowAssignRepository.RemoveRangeAsync(assigns, cancellationToken);
-
-//                    var assign = WorkflowAssign.Create(workflow.Id, orgCode, orgName);
-//                    await _workflowAssignRepository.AddAsync(assign, cancellationToken);
-//                }
-//            }
-
-//            await _workflowStepRepository.UpdateRangeAsync(changedSteps, cancellationToken);
-
-//            await AcceptTraceAsync(workflow, currentStep, cancellationToken);
-
-//            await _mediator.Publish(new AcceptWorkflowNotify(workflow), cancellationToken);
-//        }
-
-//        /// <summary>
-//        /// 办理(流转至下一节点)
-//        /// </summary>
-//        public async Task NextAsync(Workflow workflow, NextWorkflowDto dto, StepDefine nextStepBoxDefine,
-//            FlowAssignInfo flowAssignInfo, DateTime expiredTime, CancellationToken cancellationToken)
-//        {
-//            ValidatePermission(workflow);
-//            CheckWhetherRunnable(workflow.Status);
-
-//            #region 办理当前节点
-
-//            var (currentStepBox, currentStep) = GetUnCompleteStep(workflow.Steps, _sessionContext.RequiredOrgId, _sessionContext.RequiredUserId);
-
-//            var counterSignType = GetCounterSignType(currentStep.BusinessType);
-
-//            await HandleStepAsync(workflow, dto, currentStepBox, currentStep, counterSignType, cancellationToken);
-
-//            //update realhandle info
-//            _mapper.Map(dto, workflow);
-
-//            var updateSteps = new List<WorkflowStep> { currentStepBox, currentStep };
-//            //结束当前会签流程
-//            if (currentStep.StepType is EStepType.Summary && currentStep.IsInCountersign)
-//            {
-//                var currentCountersign = workflow.Countersigns.FirstOrDefault(d => d.Id == currentStep.CountersignId);
-//                if (currentCountersign is null)
-//                    throw new UserFriendlyException(
-//                        $"未查询到对应会签信息,workflowId:{workflow.Id}, countersignId:{currentStep.CountersignId}", "无效会签编号");
-
-//                //1.根据当前节点配置查找结束节点对应开始节点 2.如该开始节点与当前会签开始节点吻合说明可以结束
-
-//                //如果!=,说明未发起会签而是继承的外层会签
-//                if (currentStepBox.CountersignStartStepCode == currentCountersign.StartStepCode)
-//                {
-//                    //结束step会签信息
-//                    var countersignStartStepBox =
-//                        workflow.Steps.FirstOrDefault(d => d.Code == currentCountersign.StartStepCode);
-//                    if (countersignStartStepBox is null)
-//                        throw new UserFriendlyException(
-//                            $"未查询到会签开始stepBox, workflowId: {workflow.Id}, startStepCode: {currentCountersign.StartStepCode}", "未查询到会签开始节点");
-//                    var countersignStartStep =
-//                        countersignStartStepBox.Steps.FirstOrDefault(d => d.HasStartedCountersign && d.Id == currentCountersign.StartStepId);
-//                    if (countersignStartStep is null)
-//                        throw new UserFriendlyException(
-//                            $"未查询到会签开始step, workflowId: {workflow.Id}, startStepId: {currentCountersign.StartStepId}", "未查询到会签开始节点");
-//                    countersignStartStep.CountersignEnd();
-//                    updateSteps.Add(countersignStartStep);
-
-//                    //结束会签
-//                    currentCountersign.End(currentStep.Id, currentStep.Code, currentStep.BusinessType);
-//                    await _workflowCountersignRepository.UpdateAsync(currentCountersign, cancellationToken);
-//                }
-//            }
-
-//            await _workflowStepRepository.UpdateRangeAsync(updateSteps, cancellationToken);
-
-//            await NextTraceAsync(workflow, dto, currentStep, cancellationToken);
-
-//            #endregion
-
-//            #region 处理流程
-
-//            //检查会签是否结束,并更新当前会签节点字段
-//            var isCountersignOver = false;
-//            if (workflow.IsInCountersign() && currentStep.StepType is EStepType.Summary)
-//            {
-//                isCountersignOver = workflow.CheckIfCountersignOver();
-//                if (isCountersignOver)
-//                    workflow.EndCountersign();
-//            }
-
-//            //检查是否流转到流程终点
-//            if (nextStepBoxDefine.StepType is EStepType.End && !workflow.IsInCountersign())
-//            {
-//                var endTrace = await WorkflowEnd(workflow, dto, nextStepBoxDefine, currentStepBox, currentStep, cancellationToken);
-//                return;
-//            }
-
-//            //是否从中心流转出去,重新计算expiredTime 
-//            var isCenterToOrg = CheckIfFlowFromCenterToOrg(currentStepBox, nextStepBoxDefine);
-//            if (isCenterToOrg)
-//                workflow.CenterToOrg(CalculateExpiredTime(workflow.WorkflowDefinition.Code));//todo 过期时间
-
-//            //创建下一节点(会签汇总节点不重复创建)
-//            var nextStepBox = await CreateStepAsync(workflow, nextStepBoxDefine, dto, EWorkflowStepStatus.Created,
-//                currentStepBox, currentStep, EWorkflowTraceStatus.Normal, expiredTime, cancellationToken);
-
-//            //下一节点为汇总节点时,检查下一节点是否可办理
-//            var nextStepCanHandle = true;
-//            if (nextStepBox.StepType is EStepType.Summary && currentStep.IsInCountersign)
-//            {
-//                //同一会签Id,非汇总节点
-//                var steps = await _workflowStepRepository.QueryAsync(d =>
-//                    d.WorkflowId == workflow.Id
-//                    && d.CountersignId == currentStep.CountersignId
-//                    && d.StepType == EStepType.Normal
-//                    && !string.IsNullOrEmpty(d.ParentId));
-//                //(当前办理节点所处同一会签内的所有step全都办理完成并且如果开启了会签的step,必须会签结束)
-//                var unComplete = steps.Any(d =>
-//                    d.Status != EWorkflowStepStatus.Handled ||
-//                    (d.HasStartedCountersign && !(d.IsStartedCountersignSummary ?? false)));
-//                nextStepCanHandle = !unComplete;
-//            }
-
-//            //更新办理人
-//            workflow.UpdateHandlers(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId,
-//                flowAssignInfo.FlowAssignType, flowAssignInfo.HandlerObjects);
-
-//            if (nextStepCanHandle)
-//            {
-//                //将下一节点处理为已指派/可接办
-//                await SetNextCountersignEndAssignedAsync(nextStepBox, currentStep, cancellationToken);
-
-//                await _mediator.Publish(new CountersignEndAssigned(workflow), cancellationToken);
-//            }
-
-//            //更新实际办理节点名称、时间
-//            workflow.UpdateWorkflowActualHandleInfo(currentStepBox, currentStep,
-//                _sessionContext.RequiredUserId, _sessionContext.UserName,
-//                _sessionContext.RequiredOrgId, _sessionContext.OrgName,
-//                _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName);
-
-//            //todo 计算办理工作时长
-
-//            //更新当前办理节点信息
-//            workflow.UpdateWorkflowCurrentStepInfo(dto.IsStartCountersign, currentStep, nextStepBox.Steps.First());
-
-//            //发起会签时记录顶层会签节点
-//            if (dto.IsStartCountersign && !workflow.IsInCountersign())
-//                workflow.StartCountersign(currentStepBox.Code, counterSignType);
-
-//            //更新指派信息
-//            workflow.Assign(flowAssignInfo.FlowAssignType, flowAssignInfo.GetHandlerIds());
-
-//            await _workflowRepository.UpdateAsync(workflow, cancellationToken);
-
-//            #endregion
-
-//            #region 流转记录
-
-//            var trace = await NextTraceAsync(workflow, dto, currentStep, cancellationToken);
-
-//            #endregion
-
-//            #region 处理额外参数(短信通知、办理时限、省延期)
-
-//            //需统一处理的放在这里,与业务关联的放在业务中去处理,如:省延期
-//            //todo
-
-//            #endregion
-
-//            await _mediator.Publish(new NextStepNotify(workflow, dto, trace,
-//                isCenterToOrg, isCountersignOver,
-//                _sessionContext.RequiredOrgId, flowAssignInfo), cancellationToken);
-//        }
-
-//        /// <summary>
-//        /// 退回(返回前一节点)
-//        /// </summary>
-//        /// <returns></returns>
-//        public async Task PreviousAsync(Workflow workflow, PreviousWorkflowDto dto, CancellationToken cancellationToken)
-//        {
-//            ValidatePermission(workflow);
-//            CheckWhetherRunnable(workflow.Status);
-//            if (workflow.IsInCountersign())
-//                throw UserFriendlyException.SameMessage("会签流程不支持退回");
-//            var (currentStepBox, currentStep) = GetUnCompleteStep(workflow.Steps, _sessionContext.RequiredOrgId, _sessionContext.RequiredUserId);
-//            if (currentStepBox.StepType is EStepType.Start)
-//                throw UserFriendlyException.SameMessage("当前流程已退回到开始节点");
-
-//            //find prevStep, update handler
-//            var prevStepBox = workflow.Steps.FirstOrDefault(d => d.Id == currentStepBox.PreviousStepId);
-//            if (prevStepBox == null)
-//                throw UserFriendlyException.SameMessage("未查询到上级节点");
-//            var prevStep = prevStepBox.Steps.FirstOrDefault(d => d.Id == currentStep.PreviousStepId);
-//            if (prevStep == null)
-//                throw UserFriendlyException.SameMessage("未查询到前一节点");
-//            if (prevStep.StepType is EStepType.Start)
-//                throw UserFriendlyException.SameMessage("当前流程已退回到第一节点");
-
-//            //update trace
-//            await PreviousTraceAsync(workflow.Id, dto, currentStep, cancellationToken);
-
-//            //检查并重置上级stepbox状态为待接办
-//            await ResetStepBoxStatusAsync(prevStepBox, cancellationToken);
-
-//            //复制上一个节点为待接办
-//            var newPrevStep = await CreatePrevStepAsync(workflow, prevStep, cancellationToken);
-
-//            //remove workflow.steps
-//            await _workflowStepRepository.RemoveRangeAsync(new List<WorkflowStep> { currentStepBox, currentStep, prevStep }, cancellationToken);
-
-//            //更新当前办理节点信息
-//            workflow.UpdateWorkflowCurrentStepInfo(false, nextStep: newPrevStep);
-
-//            //更新流程可办理对象
-//            workflow.UpdatePreviousHandlers(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId, newPrevStep);
-
-//            //orgToCenter会触发重新计算期满时间,1.无需审核按当前时间进行计算 2.需审核按审核通过时间计算
-//            var isOrgToCenter = CheckIfFlowFromOrgToCenter(currentStepBox, prevStepBox);
-//            if (isOrgToCenter)
-//                workflow.OrgToCenter(CalculateExpiredTime(""));//todo 过期时间
-
-//            await _workflowRepository.UpdateAsync(workflow, cancellationToken);
-
-//            await _mediator.Publish(new PreviousNotify(workflow, dto, isOrgToCenter), cancellationToken);
-//        }
-
-//        /// <summary>
-//        /// 撤回(返回到之前任意节点)
-//        /// </summary>
-//        public async Task RecallAsync(Workflow workflow, RecallDto dto, StepDefine targetStepDefine, FlowAssignInfo flowAssignInfo, CancellationToken cancellationToken)
-//        {
-//            if (targetStepDefine.StepType is EStepType.Start or EStepType.End)
-//                throw UserFriendlyException.SameMessage("开始/结束节点不支持撤回");
-
-//            var targetStepBox = workflow.Steps.FirstOrDefault(d => d.Code == dto.NextStepCode);
-//            if (targetStepBox is null)
-//                throw UserFriendlyException.SameMessage("该流程尚未流转至该节点");
-
-//            //update uncompleted traces
-//            await RecallTraceAsync(workflow.Id, cancellationToken);
-
-//            var isOrgToCenter = await RecallAsync(workflow, dto, targetStepDefine, targetStepBox, EWorkflowTraceStatus.Recall, cancellationToken);
-
-//            workflow.ResetHandlers(flowAssignInfo.FlowAssignType, flowAssignInfo.HandlerObjects);
-
-//            await _workflowRepository.UpdateAsync(workflow, cancellationToken);
-
-//            await _mediator.Publish(new RecallNotify(workflow, dto, isOrgToCenter), cancellationToken);
-//        }
-
-//        /// <summary>
-//        /// 跳转(直接将流程跳转至任意节点)
-//        /// </summary>
-//        public async Task JumpAsync(Workflow workflow, RecallDto dto, StepDefine targetStepDefine,
-//            bool isStartCountersign, FlowAssignInfo flowAssignInfo, CancellationToken cancellationToken)
-//        {
-//            if (targetStepDefine.StepType is EStepType.Start or EStepType.End)
-//                throw UserFriendlyException.SameMessage("开始/结束节点不支持跳转");
-
-//            //update uncompleted traces
-//            await JumpTraceAsync(workflow.Id, dto, cancellationToken);
-
-//            bool isOrgToCenter = false, isCenterToOrg = false;
-//            var targetStepBox = workflow.Steps.FirstOrDefault(d => d.Code == dto.NextStepCode);
-//            if (targetStepBox == null)
-//            {
-//                //向后跳转
-
-//                //此场景并非按配置流转,默认最靠后的节点做为targetStep的prevStep
-//                var lastStepBox = workflow.Steps.MaxBy(d => d.CreationTime);
-//                if (lastStepBox is null || lastStepBox.StepType is EStepType.End)
-//                    throw new UserFriendlyException($"流程流转数据异常,未结束流程出现endStep, flowId: {workflow.Id}", "流程流转数据异常");
-
-//                targetStepBox = await CreateStepAsync(workflow, targetStepDefine, dto,
-//                    EWorkflowStepStatus.WaitForAccept, lastStepBox, lastStepBox.Steps.First(),
-//                    EWorkflowTraceStatus.Jump, workflow.ExpiredTime, cancellationToken);
-
-//                workflow.EndCountersign();
-//                workflow.ResetOption();
-
-//                //更新当前办理节点信息
-//                workflow.UpdateWorkflowCurrentStepInfo(dto.IsStartCountersign, nextStep: targetStepBox.Steps.First());
-
-//                //calc workflow expired time
-//                isCenterToOrg = CheckIfFlowFromCenterToOrg(workflow, targetStepBox);
-//                if (isCenterToOrg)
-//                    workflow.ExpiredTime = CalculateExpiredTime("");
-
-//                #region 补充中间节点处理方案(暂不需要)
-
-//                //var completeStepCodes = workflow.StepBoxes.Select(d => d.Code);
-//                //var uncompleteStepDefines = workflow.Definition.Steps.Where(d => !completeStepCodes.Contains(d.Code));
-//                //创建当前节点与目标节点中间节点
-//                //var jumpDto = new BasicWorkflowDto
-//                //{
-//                //    Opinion = "跳转补充"
-//                //};
-
-//                //foreach (var stepDefine in uncompleteStepDefines)
-//                //{
-//                //    var previousStepId = lastStepBox.Steps.Count > 1 ? lastStepBox.Id : lastStepBox.Steps.First().Id;
-//                //    if (dto.TargetStepCode == stepDefine.Code)
-//                //    {
-//                //        await CreateStepAsync(workflow, stepDefine, dto, lastStepBox.Id, previousStepId, cancellationToken);
-//                //        break;
-//                //    }
-
-//                //    //jump业务下,如果当前节点为会签节点,第一个补充节点的subStep.PreviousId无法确定从哪个子节点跳转过来,统一处理为当前节点的stepBox.Id
-//                //    lastStepBox = await CreateStepAsync(workflow, stepDefine, dto, lastStepBox.Id, previousStepId, cancellationToken);
-//                //} 
-
-//                #endregion
-//            }
-//            else
-//            {
-//                //返回之前节点
-//                isOrgToCenter = await RecallAsync(workflow, dto, targetStepDefine, targetStepBox, EWorkflowTraceStatus.Jump, cancellationToken);
-//            }
-
-//            workflow.ResetHandlers(flowAssignInfo.FlowAssignType, flowAssignInfo.HandlerObjects);
-//            await _workflowRepository.UpdateAsync(workflow, cancellationToken);
-
-//            await _mediator.Publish(new JumpNotify(workflow, dto, flowAssignInfo, isCenterToOrg, isOrgToCenter), cancellationToken);
-//        }
-
-//        /// <summary>
-//        /// 重办
-//        /// </summary>
-//        public async Task RedoAsync(Workflow workflow, RecallDto dto, StepDefine targetStepDefine,
-//            FlowAssignInfo flowAssignInfo, CancellationToken cancellationToken)
-//        {
-//            if (targetStepDefine.StepType is EStepType.Start or EStepType.End)
-//                throw UserFriendlyException.SameMessage("开始/结束节点不支持重办");
-
-//            var targetStepBox = workflow.Steps.FirstOrDefault(d => d.Code == dto.NextStepCode);
-//            if (targetStepBox is null)
-//                throw UserFriendlyException.SameMessage("未找到该节点配置");
-
-//            var isOrgToCenter = await RecallAsync(workflow, dto, targetStepDefine, targetStepBox, EWorkflowTraceStatus.Redo, cancellationToken);
-
-//            workflow.Redo();
-//            workflow.ResetHandlers(flowAssignInfo.FlowAssignType, flowAssignInfo.HandlerObjects);
-
-//            //todo calc expiredTime
-//            //dto.Extension.TimeLimitCount
-
-
-//            await _workflowRepository.UpdateAsync(workflow, cancellationToken);
-
-//            await _mediator.Publish(new RedoNotify(workflow, dto, isOrgToCenter), cancellationToken);
-//        }
-
-//        /// <summary>
-//        /// 否决(审批流程不通过)
-//        /// </summary>
-//        /// <returns></returns>
-//        public async Task RejectAsync(Workflow workflow, BasicWorkflowDto dto, CancellationToken cancellationToken)
-//        {
-//            var (currentStepBox, currentStep) = GetUnCompleteStep(workflow.Steps, _sessionContext.RequiredOrgId, _sessionContext.RequiredUserId);
-
-//            var endStepDefine = workflow.WorkflowDefinition.FindEndStepDefine();
-
-//            var endTrace = await WorkflowEnd(workflow, dto, endStepDefine, currentStepBox, currentStep, cancellationToken);
-
-//            await _mediator.Publish(new RejectNotify(workflow, dto), cancellationToken);
-//        }
-
-//        /// <summary>
-//        /// 补充
-//        /// </summary>
-//        /// <returns></returns>
-//        public async Task SupplementAsync(Workflow workflow, EndWorkflowDto dto, CancellationToken cancellationToken)
-//        {
-//            CheckWhetherRunnable(workflow.Status);
-//            //todo 检查当前办理人是否为该流程中的办理人
-
-//            var supplement = _mapper.Map<WorkflowSupplement>(dto);
-//            await _workflowSupplementRepository.AddAsync(supplement, cancellationToken);
-//        }
-
-//        /// <summary>
-//        /// 终止流程
-//        /// </summary>
-//        public async Task TerminateAsync(TerminateDto dto, CancellationToken cancellationToken)
-//        {
-//            var workflow = await _workflowRepository.GetAsync(dto.WorkflowId, cancellationToken);
-//            if (workflow == null)
-//                throw UserFriendlyException.SameMessage("无效的流程编号");
-//            //workflow.Terminate(dto.Opinion);
-//            await _workflowRepository.UpdateAsync(workflow, cancellationToken);
-
-//            await _mediator.Publish(new TerminalWorkflowNotify(workflow), cancellationToken);
-//        }
-
-//        /// <summary>
-//        /// 根据stepCode查询流程配置中对应的节点
-//        /// </summary>
-//        public StepDefine GetStepDefine(WorkflowDefinition workflowDefinition, string stepCode)
-//        {
-//            if (workflowDefinition == null) throw new ArgumentNullException(nameof(workflowDefinition));
-//            if (string.IsNullOrEmpty(stepCode)) throw new ArgumentNullException(nameof(stepCode));
-//            var stepDefine = workflowDefinition.FindStepDefine(stepCode);
-//            if (stepDefine == null)
-//                throw new UserFriendlyException($"未找到流程中对应的节点,DefineCode: {workflowDefinition.Code}, stepCode: {stepCode}",
-//                    "未查询到对应节点");
-//            return stepDefine;
-//        }
-
-//        /// <summary>
-//        /// 查询当前待办节点的下一级节点配置(办理参数)
-//        /// </summary>
-//        public IReadOnlyList<StepDefine> GetNextStepDefines(Workflow workflow)
-//        {
-//            var (currentStepBox, _) = GetUnCompleteStep(workflow.Steps, _sessionContext.RequiredOrgId, _sessionContext.RequiredUserId);
-//            return workflow.WorkflowDefinition.FindStepDefines(currentStepBox.NextSteps.Select(d => d.Code));
-//        }
-
-//        /// <summary>
-//        /// 查找当前办理节点
-//        /// </summary>
-//        public (WorkflowStep StepBox, WorkflowStep Step) FindCurrentStep(Workflow workflow) =>
-//            GetUnCompleteStep(workflow.Steps, _sessionContext.RequiredOrgId, _sessionContext.RequiredUserId);
-
-//        /// <summary>
-//        /// 查询待回访部门
-//        /// </summary>
-//        /// <returns></returns>
-//        public async Task<(Kv, IReadOnlyList<Kv>)> GetUnvisitOrgsAsync(string workflowId, CancellationToken cancellationToken)
-//        {
-//            var workflow = await GetWorkflowAsync(workflowId, withSteps: true, cancellationToken: cancellationToken);
-//            if (workflow.CounterSignType is not ECounterSignType.Center)
-//                return new(new Kv(workflow.ActualHandleOrgCode, workflow.ActualHandleOrgName), new List<Kv>());
-//            var steps = workflow.Steps
-//                .Where(d => d.StepType is EStepType.Normal && d.BusinessType is EBusinessType.Department)
-//                .SelectMany(d => d.Steps)
-//                .ToList();
-//            var items = steps.Select(d => new Kv(d.HandlerOrgId, d.HandlerOrgName)).ToList();
-//            return (new Kv(workflow.ActualHandleOrgCode, workflow.ActualHandleOrgName), items);
-//        }
-
-//        /// <summary>
-//        /// 更新一级部门信息
-//        /// </summary>
-//        public async Task UpdateOrgLevelOneAsync(Workflow workflow, string orgCode, string orgName, CancellationToken cancellationToken)
-//        {
-//            workflow.UpdateOrgLevelOne(orgCode, orgName);
-//            await _workflowRepository.UpdateAsync(workflow, cancellationToken);
-//        }
-
-//        /// <summary>
-//        /// 依据配置过滤下一节点
-//        /// </summary>
-//        public List<StepDefine> NextStepDefineFilter(EPathPolicy pathPolicy, List<StepDefine> nextStepDefines)
-//        {
-//            switch (pathPolicy)
-//            {
-//                case EPathPolicy.DirectUpper:
-//                    break;
-//                case EPathPolicy.DirectUpperCenterIsTop:
-//                    var currentOrgLevel = _sessionContext.RequiredOrgId.CalcOrgLevel();
-//                    if (currentOrgLevel == 1)
-//                    {
-//                        nextStepDefines = nextStepDefines.Where(d => d.IsCenter()).ToList();
-//                    }
-//                    else
-//                    {
-//                        var upperLevel = (--currentOrgLevel).ToString();
-//                        nextStepDefines = nextStepDefines
-//                            .Where(d => d.HandlerType is EHandlerType.OrgLevel &&
-//                                        d.HandlerTypeItems.Any(x => x.Key == upperLevel))
-//                            .ToList();
-//                    }
-
-//                    break;
-//                default:
-//                    throw new ArgumentOutOfRangeException();
-//            }
-
-//            return nextStepDefines;
-//        }
-
-//        /// <summary>
-//        /// 撤销流程
-//        /// </summary>
-//        public async Task CancelAsync(CancelDto dto, CancellationToken cancellationToken)
-//        {
-//            var workflow = await GetWorkflowAsync(dto.WorkflowId, withDefine: true, withSteps: true, cancellationToken: cancellationToken);
-
-//            var (currentStepBox, currentStep) = GetUnCompleteStep(workflow.Steps, _sessionContext.RequiredOrgId, _sessionContext.RequiredUserId);
-
-//            var endStepDefine = workflow.WorkflowDefinition.FindEndStepDefine();
-
-//            var basicDto = _mapper.Map<BasicWorkflowDto>(dto);
-//            var endTrace = await WorkflowEnd(workflow, basicDto, endStepDefine, currentStepBox, currentStep, cancellationToken);
-
-//            await _mediator.Publish(new CancelWorkflowNotify(workflow), cancellationToken);
-//        }
-
-//        #region private method
-
-//        /// <summary>
-//        /// 流程结束
-//        /// </summary>
-//        private async Task<WorkflowTrace> WorkflowEnd(Workflow workflow, BasicWorkflowDto dto, StepDefine nextStepBoxDefine,
-//            WorkflowStep currentStepBox, WorkflowStep currentStep, CancellationToken cancellationToken)
-//        {
-//            //create endStep
-//            var (_, endStep) = await CreateEndStepAsync(workflow, nextStepBoxDefine, currentStepBox, currentStep, cancellationToken);
-
-//            //update endTrace
-//            var endTrace = await NextTraceAsync(workflow, dto, endStep, cancellationToken);
-
-//            workflow.Complete();
-
-//            await _workflowRepository.UpdateAsync(workflow, cancellationToken);
-
-//            await _mediator.Publish(new EndWorkflowNotify(workflow, endTrace), cancellationToken);
-
-//            return endTrace;
-//        }
-
-//        /// <summary>
-//        /// 判断会签类型(中心会签或部门会签)
-//        /// </summary>
-//        /// <param name="businessType"></param>
-//        /// <returns></returns>
-//        /// <exception cref="ArgumentOutOfRangeException"></exception>
-//        private ECounterSignType GetCounterSignType(EBusinessType businessType) =>
-//            businessType switch
-//            {
-//                EBusinessType.Center => ECounterSignType.Center,
-//                EBusinessType.Send => ECounterSignType.Center,
-//                EBusinessType.Department => ECounterSignType.Department,
-//                _ => throw new ArgumentOutOfRangeException(nameof(businessType), businessType, null)
-//            };
-
-//        /// <summary>
-//        /// 办理节点
-//        /// </summary>
-//        private async Task HandleStepAsync(Workflow workflow, BasicWorkflowDto dto, WorkflowStep currentStepBox, WorkflowStep currentStep,
-//            ECounterSignType counterSignType, CancellationToken cancellationToken)
-//        {
-//            if (currentStep.Status is EWorkflowStepStatus.Handled or EWorkflowStepStatus.Created)
-//                throw UserFriendlyException.SameMessage("当前节点状态无法办理");
-
-//            if (currentStep.Status is EWorkflowStepStatus.WaitForAccept)
-//                await AcceptAsync(workflow,
-//                    _sessionContext.RequiredUserId,
-//                    _sessionContext.UserName,
-//                    _sessionContext.RequiredOrgId,
-//                    _sessionContext.OrgName,
-//                    cancellationToken);
-//            if (currentStep.StepType is EStepType.End)
-//                throw new UserFriendlyException("当前流程已流转到最终步骤");
-
-//            //创建会签数据
-//            if (dto.IsStartCountersign)
-//                await StartCountersignAsync(workflow, dto, currentStepBox, currentStep, counterSignType, cancellationToken);
-
-//            _mapper.Map(dto, currentStep);
-
-//            //step办理状态
-//            currentStep.Handle(
-//                _sessionContext.RequiredUserId, _sessionContext.UserName,
-//                _sessionContext.RequiredOrgId, _sessionContext.OrgName,
-//                _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName,
-//                dto.NextStepCode);
-
-//            //stepBox办理状态
-//            currentStepBox.CheckStepBoxStatusAndUpdate();
-//        }
-
-//        /// <summary>
-//        /// 开始会签(创建会签数据,更新currentStep会签数据)
-//        /// </summary>
-//        private async Task StartCountersignAsync(Workflow workflow, BasicWorkflowDto dto,
-//            WorkflowStep currentStepBox, WorkflowStep currentStep, ECounterSignType counterSignType,
-//            CancellationToken cancellationToken)
-//        {
-//            var countersign = await CreateCountersignAsync(workflow.Id, currentStep, currentStepBox.CountersignEndStepCode,
-//                dto.NextHandlers.Count, counterSignType, currentStep.CountersignId, cancellationToken);
-//            currentStep.StartCountersign(countersign.Id);
-//        }
-
-//        /// <summary>
-//        /// 检查是否从中心流转至部门
-//        /// </summary>
-//        private bool CheckIfFlowFromCenterToOrg(WorkflowStep sourceStepBox, StepDefine targetStepBoxDefine)
-//        {
-//            var isFromCenter = sourceStepBox.IsCenter();
-//            if (!isFromCenter) return false;
-
-//            var isToOrg = targetStepBoxDefine.IsOrg();
-//            return isFromCenter && isToOrg;
-//        }
-
-//        /// <summary>
-//        /// 检查是否从中心流转至部门
-//        /// </summary>
-//        private bool CheckIfFlowFromCenterToOrg(Workflow workflow, WorkflowStep targetStepBox)
-//        {
-//            var isToOrg = targetStepBox.IsOrg();
-//            if (!isToOrg) return false;
-
-//            var isFromCenter = workflow.Steps.All(d => d.BusinessType is not EBusinessType.Department);
-//            return isFromCenter && isToOrg;
-//        }
-
-//        /// <summary>
-//        /// 检查是否从部门流转至中心
-//        /// </summary>
-//        private bool CheckIfFlowFromOrgToCenter(WorkflowStep sourceStepBox, StepDefine targetStepBoxDefine)
-//        {
-//            var isFromOrg = sourceStepBox.IsOrg();
-//            if (!isFromOrg) return false;
-
-//            var isToCenter = targetStepBoxDefine.IsCenter();
-//            return isFromOrg && isToCenter;
-//        }
-
-//        /// <summary>
-//        /// 检查是否从部门流转至中心
-//        /// </summary>
-//        private bool CheckIfFlowFromOrgToCenter(WorkflowStep sourceStepBox, WorkflowStep targetStepBox)
-//        {
-//            var isFromOrg = sourceStepBox.IsOrg();
-//            if (!isFromOrg) return false;
-
-//            var isToCenter = targetStepBox.IsCenter();
-//            return isFromOrg && isToCenter;
-//        }
-
-//        /// <summary>
-//        /// 检查是否从部门流转至中心
-//        /// </summary>
-//        private bool CheckIfFlowFromOrgToCenter(Workflow workflow, WorkflowStep targetStepBox)
-//        {
-//            var isToCenter = targetStepBox.IsCenter();
-//            if (!isToCenter) return false;
-
-//            var isFromOrg = workflow.Steps.Any(d => d.BusinessType is EBusinessType.Department);
-//            return isFromOrg && isToCenter;
-//        }
-
-//        /// <summary>
-//        /// 复制一个节点为待接办
-//        /// </summary>
-//        private async Task<WorkflowStep> CreatePrevStepAsync(Workflow workflow, WorkflowStep step, CancellationToken cancellationToken)
-//        {
-//            step.Reset();
-//            var newStep = _mapper.Map<WorkflowStep>(step);
-//            newStep.Status = EWorkflowStepStatus.WaitForAccept;
-//            newStep.PreviousStepId = step.PreviousStepId;
-//            newStep.IsMain = step.IsMain;
-//            newStep.ParentId = step.ParentId;
-//            newStep.Handlers = step.Handlers;
-//            newStep.StartCountersignId = step.StartCountersignId;
-//            newStep.CountersignId = step.CountersignId;
-//            newStep.IsStartedCountersignSummary = step.IsStartedCountersignSummary;
-//            await _workflowStepRepository.AddAsync(newStep, cancellationToken);
-
-//            await CreateTraceAsync(workflow, newStep, EWorkflowTraceStatus.Previous, cancellationToken);
-
-//            return newStep;
-//        }
-
-//        /// <summary>
-//        /// 检查并重置目标stepbox状态为待接办
-//        /// </summary>
-//        private async Task ResetStepBoxStatusAsync(WorkflowStep stepBox, CancellationToken cancellationToken)
-//        {
-//            if (stepBox.Status is EWorkflowStepStatus.Handled)
-//            {
-//                stepBox.Status = EWorkflowStepStatus.WaitForAccept;
-//                await _workflowStepRepository.UpdateAsync(stepBox, cancellationToken);
-//            }
-//        }
-
-//        private async Task<WorkflowCountersign> CreateCountersignAsync(
-//            string workflowId, WorkflowStep startStep, string endStepCode, int count,
-//            ECounterSignType counterSignType, string? parentId = null, CancellationToken cancellationToken = default)
-//        {
-//            var countersign = new WorkflowCountersign
-//            {
-//                WorkflowId = workflowId,
-//                StartStepId = startStep.Id,
-//                StartStepCode = startStep.Code,
-//                StartStepBusiType = startStep.BusinessType,
-//                EndStepCode = endStepCode,
-//                Members = count,
-//                ParentId = parentId,
-//                CounterSignType = counterSignType,
-//            };
-//            await _workflowCountersignRepository.AddAsync(countersign, cancellationToken);
-//            return countersign;
-//        }
-
-
-//        /// <summary>
-//        /// 更新下级汇总节点可办理状态
-//        /// </summary>
-//        /// <param name="nextStepBox"></param>
-//        /// <param name="currentStep"></param>
-//        /// <param name="cancellationToken"></param>
-//        /// <returns></returns>
-//        private async Task SetNextCountersignEndAssignedAsync(WorkflowStep nextStepBox, WorkflowStep currentStep, CancellationToken cancellationToken)
-//        {
-//            var nextSteps = currentStep.CountersignPosition is ECountersignPosition.Inner
-//                ? nextStepBox.Steps.Where(d => d.CountersignId == currentStep.CountersignId).ToList()
-//                : nextStepBox.Steps.Where(d => d.PreviousStepId == currentStep.Id).ToList();
-
-//            if (!nextSteps.Any())
-//                throw new UserFriendlyException($"未查询到下一节点, currentStepId: {currentStep.Id}");
-
-//            foreach (var nextStep in nextSteps)
-//            {
-//                nextStep.SetAssigned();
-//            }
-
-//            await _workflowStepRepository.UpdateRangeAsync(nextSteps, cancellationToken);
-//        }
-
-//        private async Task JumpTraceAsync(string workflowId, RecallDto dto, CancellationToken cancellationToken)
-//        {
-//            //未办理的traces
-//            var uncompleteTraces =
-//                await _workflowTraceRepository.QueryAsync(d =>
-//                    d.WorkflowId == workflowId && string.IsNullOrEmpty(d.HandlerId));
-//            foreach (var trace in uncompleteTraces)
-//            {
-//                trace.Jump(
-//                    _sessionContext.RequiredUserId,
-//                    _sessionContext.UserName,
-//                    _sessionContext.RequiredOrgId,
-//                    _sessionContext.OrgName,
-//                    dto.Opinion);
-//            }
-
-//            await _workflowTraceRepository.UpdateRangeAsync(uncompleteTraces, cancellationToken);
-//        }
-
-//        private async Task RecallTraceAsync(string workflowId, CancellationToken cancellationToken)
-//        {
-//            //未办理的traces
-//            var uncompleteTraces =
-//                await _workflowTraceRepository.QueryAsync(d =>
-//                    d.WorkflowId == workflowId && string.IsNullOrEmpty(d.HandlerId));
-
-//            if (uncompleteTraces.Any())
-//            {
-//                foreach (var trace in uncompleteTraces)
-//                {
-//                    trace.Complete(
-//                        _sessionContext.RequiredUserId,
-//                        _sessionContext.UserName,
-//                        _sessionContext.RequiredOrgId,
-//                        _sessionContext.OrgName);
-//                }
-
-//                await _workflowTraceRepository.UpdateRangeAsync(uncompleteTraces, cancellationToken);
-//            }
-//        }
-
-//        private async Task PreviousTraceAsync(string workflowId, PreviousWorkflowDto dto, WorkflowStep step, CancellationToken cancellationToken)
-//        {
-//            var trace = await GetWorkflowTraceAsync(workflowId, step.Id, cancellationToken);
-//            _mapper.Map(dto, trace);
-//            trace.Complete(
-//                _sessionContext.RequiredUserId,
-//                _sessionContext.UserName,
-//                _sessionContext.RequiredOrgId,
-//                _sessionContext.OrgName);
-//            await _workflowTraceRepository.UpdateAsync(trace, cancellationToken);
-//        }
-
-//        //private async Task EndTraceAsync(Workflow workflow, BasicWorkflowDto dto, WorkflowStep step, CancellationToken cancellationToken)
-//        //{
-//        //    var trace = _mapper.Map<WorkflowTrace>(step);
-//        //    trace.Status = EWorkflowTraceStatus.Normal;
-//        //    trace.ExpiredTime = workflow.ExpiredTime;
-//        //    trace.TimeLimit = workflow.TimeLimit;
-//        //    await _workflowTraceRepository.AddAsync(trace, cancellationToken);
-//        //}
-
-//        private async Task<WorkflowTrace> NextTraceAsync(Workflow workflow, BasicWorkflowDto dto, WorkflowStep step, CancellationToken cancellationToken)
-//        {
-//            var trace = await GetWorkflowTraceAsync(workflow.Id, step.Id, cancellationToken);
-//            _mapper.Map(dto, trace);
-//            _mapper.Map(step, trace);
-//            await _workflowTraceRepository.UpdateAsync(trace, cancellationToken);
-
-//            return trace;
-//        }
-
-//        private async Task AcceptTraceAsync(Workflow workflow, WorkflowStep step, CancellationToken cancellationToken)
-//        {
-//            var trace = await GetWorkflowTraceAsync(workflow.Id, step.Id, cancellationToken);
-//            _mapper.Map(step, trace);
-//            await _workflowTraceRepository.UpdateAsync(trace, cancellationToken);
-//        }
-
-//        private async Task CreateTraceAsync(Workflow workflow, WorkflowStep currentStep,
-//            EWorkflowTraceStatus traceStatus = EWorkflowTraceStatus.Normal, CancellationToken cancellationToken = default)
-//        {
-//            var trace = _mapper.Map<WorkflowTrace>(currentStep);
-//            trace.Status = traceStatus;
-
-//            //1.如果是汇总节点,trace.parentId=会签开始节点对应的trace.parentId(即与会签开始节点trace同级)
-//            //2.普通节点:2.1: in 判断上级节点是否发起会签,有则赋值parentId为上级trace.Id, 2.2: outer 与上级节点trace保持同级,取值上级节点对应trace.parentId
-
-//            if (currentStep.StepType is EStepType.Summary)
-//            {
-//                if (currentStep.IsInCountersign)
-//                {
-//                    var countersign =
-//                        await _workflowCountersignRepository.GetAsync(currentStep.CountersignId!, cancellationToken);
-//                    if (countersign == null)
-//                        throw new UserFriendlyException(
-//                            $"汇总节点处于会签中,未查询到对应会签,countersignId: {currentStep.CountersignId}");
-//                    var startTrace = await GetWorkflowTraceAsync(workflow.Id, countersign.StartStepId, cancellationToken);
-//                    trace.ParentId = startTrace.ParentId;
-//                }
-//            }
-//            else if (currentStep.StepType is EStepType.Normal)
-//            {
-//                if (currentStep.CountersignPosition is ECountersignPosition.Inner)
-//                {
-//                    var prevTrace = await GetWorkflowTraceAsync(workflow.Id, currentStep.PreviousStepId, cancellationToken);
-//                    trace.ParentId = prevTrace.Id;
-//                }
-//                else if (currentStep.CountersignPosition is ECountersignPosition.Outer)
-//                {
-//                    var prevTrace = await GetWorkflowTraceAsync(workflow.Id, currentStep.PreviousStepId, cancellationToken);
-//                    trace.ParentId = prevTrace.ParentId;
-//                }
-//            }
-//            ////处于会签中的节点,其对应的trace.parentId赋值上级trace.Id
-//            //if (currentStep.CountersignPosition is ECountersignPosition.InCountersign)
-//            //{
-//            //    var parentTrace = await GetWorkflowTraceAsync(workflow.Id, currentStep.PrevStepId, cancellationToken);
-//            //    trace.ParentId = parentTrace.Id;
-//            //}
-
-//            await _workflowTraceRepository.AddAsync(trace, cancellationToken);
-//        }
-
-//        private async Task<WorkflowTrace> GetWorkflowTraceAsync(string workflowId, string stepId, CancellationToken cancellationToken)
-//        {
-//            var parentTrace = await _workflowTraceRepository.GetAsync(d =>
-//                d.WorkflowId == workflowId && d.StepId == stepId, cancellationToken);
-//            if (parentTrace == null)
-//                throw new UserFriendlyException($"未找到对应trace, workflowId: {workflowId}, stepId: {stepId}");
-//            return parentTrace;
-//        }
-
-//        private async Task<bool> RecallAsync(Workflow workflow, BasicWorkflowDto dto, StepDefine targetStepDefine, WorkflowStep targetStepBox, EWorkflowTraceStatus traceStatus, CancellationToken cancellationToken)
-//        {
-//            //get targetStep's previous
-//            var targetPrevStepBox = workflow.Steps.FirstOrDefault(d => d.Id == targetStepBox.PreviousStepId);
-//            if (targetPrevStepBox == null)
-//                throw new UserFriendlyException($"{nameof(RecallAsync)}, 未找到目标节点的前一节点, flowId: {workflow.Id}, targetStepBoxPrevId: {targetPrevStepBox?.PreviousStepId}");
-//            //真实的前一节点并不存在(非正常流转造成的),所以取前一stepbox任意一个step替代
-//            var targetPrevStep = targetPrevStepBox.Steps.FirstOrDefault();
-//            if (targetPrevStep == null)
-//                throw new UserFriendlyException($"{nameof(RecallAsync)}, 未找到目标节点的前一节点, flowId: {workflow.Id}");
-
-//            //查询所有目标节点之后的节点,然后删掉(包括目标节点)
-//            var removeSteps = GetStepsBehindTargetStepBox(workflow.Steps, targetStepBox);
-//            if (removeSteps.Any())
-//            {
-//                await _workflowStepRepository.RemoveRangeAsync(removeSteps, cancellationToken);
-//                workflow.Steps.RemoveAll(d => removeSteps.Contains(d));
-//            }
-
-//            workflow.EndCountersign();
-//            workflow.ResetOption();
-
-//            //recreate targetStep
-//            var targetStepBoxNew = await CreateStepAsync(workflow, targetStepDefine, dto, EWorkflowStepStatus.WaitForAccept,
-//                 targetPrevStepBox, targetPrevStep, traceStatus, workflow.ExpiredTime, cancellationToken);
-
-//            //更新当前办理节点信息
-//            workflow.UpdateWorkflowCurrentStepInfo(dto.IsStartCountersign, nextStep: targetStepBoxNew.Steps.First());
-
-//            //calc workflow expired time
-//            var isOrgToCenter = CheckIfFlowFromOrgToCenter(workflow, targetStepBox);
-//            if (isOrgToCenter)
-//                workflow.ExpiredTime = CalculateExpiredTime("");
-
-//            return isOrgToCenter;
-//        }
-
-//        private ICollection<WorkflowStep> GetStepsBehindTargetStepBox(List<WorkflowStep> stepBoxes, WorkflowStep targetStepBox)
-//        {
-//            var steps = GetStepsIncludeStepBox(targetStepBox);
-//            var nextStepBoxes = stepBoxes.Where(d => d.PreviousStepId == targetStepBox.Id).ToList();
-//            if (!nextStepBoxes.Any())
-//                return steps;
-//            foreach (var nextStepBox in nextStepBoxes)
-//            {
-//                steps.AddRange(GetStepsBehindTargetStepBox(stepBoxes, nextStepBox));
-//            }
-//            return steps;
-//        }
-
-//        private List<WorkflowStep> GetStepsIncludeStepBox(WorkflowStep stepBox)
-//        {
-//            var steps = new List<WorkflowStep> { stepBox };
-//            steps.AddRange(stepBox.Steps);
-//            return steps;
-//        }
-
-//        private static void CheckWhetherRunnable(EWorkflowStatus status)
-//        {
-//            if (status != EWorkflowStatus.Runnable)
-//                throw UserFriendlyException.SameMessage("当前流程状态不可继续流转");
-//        }
-
-//        private void ValidatePermission(Workflow workflow)
-//        {
-//            if (!workflow.CanHandle(_sessionContext.RequiredUserId, _sessionContext.RequiredOrgId))
-//                throw UserFriendlyException.SameMessage("无办理权限");
-//        }
-
-//        private async Task<(WorkflowStep startStepBox, WorkflowStep startStep, WorkflowStep firstStepBox)> CreateStartAndFirstStepAsync(
-//            Workflow workflow, BasicWorkflowDto dto, CancellationToken cancellationToken)
-//        {
-//            if (workflow.Steps.Any())
-//                throw UserFriendlyException.SameMessage("无法重复创建开始节点");
-
-//            var startStepDefinition = workflow.WorkflowDefinition.Steps.FirstOrDefault(d => d.StepType == EStepType.Start);
-//            if (startStepDefinition == null)
-//                throw new UserFriendlyException($"模板未配置开始节点, defineCode: {workflow.WorkflowDefinition.Code}", "模板未配置开始节点");
-
-//            var startStepBox = CreateStepBox(workflow.Id, startStepDefinition, string.Empty);
-//            await _workflowStepRepository.AddAsync(startStepBox, cancellationToken);
-
-
-//            //start节点的办理人分类默认为用户,即为当前发起流程的操作员
-//            var handler = new Kv { Key = _sessionContext.RequiredUserId, Value = _sessionContext.UserName };
-
-//            //开始节点的下一个节点(工单业务:话务员节点)
-//            var firstStepCode = workflow.WorkflowDefinition.FindStartStepDefine().NextSteps.First().Code;
-//            var startStep = await CreateStartSubStepAsync(handler, firstStepCode, startStepBox, dto, cancellationToken);
-
-//            //开始节点trace
-//            await CreateTraceAsync(workflow, startStep, cancellationToken: cancellationToken);
-
-//            //创建firstStep
-//            var firsStepDefine = workflow.WorkflowDefinition.FindStepDefine(firstStepCode);
-//            var firstStepBox = await CreateStepAsync(workflow, firsStepDefine, dto, EWorkflowStepStatus.WaitForHandle,
-//                startStepBox, startStep, EWorkflowTraceStatus.Normal, workflow.ExpiredTime, cancellationToken);
-
-//            return (startStepBox, startStep, firstStepBox);
-//        }
-
-//        private async Task<(WorkflowStep stepBox, WorkflowStep step)> CreateEndStepAsync(
-//            Workflow workflow,
-//            StepDefine endStepDefine,
-//            WorkflowStep prevStepBox,
-//            WorkflowStep prevStep,
-//            CancellationToken cancellationToken)
-//        {
-//            if (workflow.Steps.Any(d => d.StepType == EStepType.End))
-//                throw UserFriendlyException.SameMessage("无法重复创建结束节点");
-
-//            var stepBox = CreateStepBox(workflow.Id, endStepDefine, prevStepBox.Id);
-//            await _workflowStepRepository.AddAsync(stepBox, cancellationToken);
-
-//            var handler = new Kv { Key = _sessionContext.RequiredUserId, Value = _sessionContext.UserName };
-//            var step = await CreateEndSubStepAsync(handler, stepBox, prevStep, cancellationToken);
-
-//            //end trace
-//            await CreateTraceAsync(workflow, step, cancellationToken: cancellationToken);
-
-//            return (stepBox, step);
-//        }
-
-//        /// <summary>
-//        /// 创建节点(不含开始、结束节点)
-//        /// </summary>
-//        private async Task<WorkflowStep> CreateStepAsync(
-//        Workflow workflow,
-//        StepDefine stepBoxDefine,
-//        BasicWorkflowDto dto,
-//        EWorkflowStepStatus status,
-//        WorkflowStep prevStepBox,
-//        WorkflowStep prevStep,
-//        EWorkflowTraceStatus traceStatus,
-//        DateTime expiredTime,
-//        CancellationToken cancellationToken)
-//        {
-//            if (stepBoxDefine.StepType is EStepType.Start or EStepType.End)
-//                throw new UserFriendlyException("该方法不支持创建开始或结束节点");
-//            var stepBox = workflow.Steps.FirstOrDefault(d => d.Code == stepBoxDefine.Code);
-//            if (stepBox == null)
-//            {
-//                stepBox = CreateStepBox(workflow.Id, stepBoxDefine, prevStepBox.Id);
-//                await _workflowStepRepository.AddAsync(stepBox, cancellationToken);
-//                workflow.Steps.Add(stepBox);
-//            }
-//            else if (stepBox.Status != EWorkflowStepStatus.Created)
-//            {
-//                stepBox.Status = EWorkflowStepStatus.Created;
-//                await _workflowStepRepository.UpdateAsync(stepBox, cancellationToken);
-//            }
-
-//            //下一节点为汇总节点时,同一会签只需要创建一次汇总节点
-//            if (stepBoxDefine.StepType is EStepType.Summary && prevStep.CountersignPosition == ECountersignPosition.Inner)
-//            {
-//                var step = stepBox.Steps.FirstOrDefault(d =>
-//                    d.IsInCountersign && d.CountersignId == prevStep.CountersignId);
-//                if (step != null)
-//                    return stepBox;
-//            }
-
-//            await CreateSubStepsAsync(workflow, stepBoxDefine, dto, stepBox, status, prevStep, traceStatus, expiredTime, cancellationToken);
-
-
-//            return stepBox;
-//        }
-
-//        private async Task<WorkflowStep> CreateStartSubStepAsync(
-//            Kv handler,
-//            string nextStepCode,
-//            WorkflowStep stepBox,
-//            BasicWorkflowDto dto,
-//            CancellationToken cancellationToken)
-//        {
-//            //开始节点既不发起会签,也不处于会签中
-//            var subStep = CreateSubStep(stepBox, new List<Kv> { handler }, nextStepCode, null,
-//                null, null, EWorkflowStepStatus.Handled, ECountersignPosition.None, DateTime.Today,
-//                _mapper.Map<StepExtension>(dto.Extension));
-//            subStep.Accept(_sessionContext.RequiredUserId, _sessionContext.UserName,
-//                _sessionContext.RequiredOrgId, _sessionContext.OrgName);
-
-//            //step办理状态
-//            subStep.Handle(_sessionContext.RequiredUserId, _sessionContext.UserName,
-//                _sessionContext.RequiredOrgId, _sessionContext.OrgName,
-//                _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName,
-//                nextStepCode);
-
-//            subStep.Opinion = "流程开启";
-//            stepBox.Steps.Add(subStep);
-//            await _workflowStepRepository.AddAsync(subStep, cancellationToken);
-//            return subStep;
-//        }
-
-//        private async Task<WorkflowStep> CreateEndSubStepAsync(
-//            Kv handler,
-//            WorkflowStep currentStepBox,
-//            WorkflowStep prevStep,
-//            CancellationToken cancellationToken)
-//        {
-//            var subStep = CreateSubStep(currentStepBox, new List<Kv> { handler }, null, null, prevStep.Id,
-//                null, EWorkflowStepStatus.Handled, ECountersignPosition.None, DateTime.Today, new());
-//            subStep.Accept(_sessionContext.RequiredUserId, _sessionContext.UserName, _sessionContext.RequiredOrgId,
-//                _sessionContext.OrgName);
-//            subStep.Handle(_sessionContext.RequiredUserId, _sessionContext.UserName,
-//                _sessionContext.RequiredOrgId, _sessionContext.OrgName,
-//                _sessionContext.OrgAreaCode, _sessionContext.OrgAreaName,
-//                string.Empty);
-
-//            currentStepBox.Steps.Add(subStep);
-//            await _workflowStepRepository.AddAsync(subStep, cancellationToken);
-//            return subStep;
-//        }
-
-//        private async Task CreateSubStepsAsync(
-//            Workflow workflow,
-//            StepDefine stepBoxDefine,
-//            BasicWorkflowDto dto,
-//            WorkflowStep stepBox,
-//            EWorkflowStepStatus stepStatus,
-//            WorkflowStep prevStep,
-//            EWorkflowTraceStatus traceStatus,
-//            DateTime expiredTime,
-//            CancellationToken cancellationToken = default)
-//        {
-//            var countersignStatus = stepBoxDefine.StepType is EStepType.Summary
-//                ? prevStep.IsInCountersign
-//                    ? ECountersignPosition.Inner
-//                    : ECountersignPosition.None
-//                : prevStep.GetNextStepCountersignPosition();
-
-//            var countersignId = dto.IsStartCountersign ? prevStep.StartCountersignId : prevStep.CountersignId;
-
-//            List<WorkflowStep> subSteps;
-//            var stepExtension = _mapper.Map<StepExtension>(dto.Extension);
-//            if (stepBoxDefine.HandlerType is EHandlerType.AssignedUser or EHandlerType.AssignedOrg)
-//            {
-//                subSteps = CreateSubSteps(dto.IsStartCountersign, stepBox, stepBox.HandlerClassifies, dto.NextStepCode, dto.NextMainHandler,
-//                    prevStep?.Id, countersignId, stepStatus, countersignStatus, expiredTime, stepExtension);
-//            }
-//            else
-//            {
-//                if (stepBoxDefine.HandlerType != EHandlerType.Role && !dto.NextHandlers.Any())
-//                    throw new UserFriendlyException("未指定节点处理者");
-//                subSteps = CreateSubSteps(dto.IsStartCountersign, stepBox, dto.NextHandlers, dto.NextStepCode, dto.NextMainHandler,
-//                    prevStep?.Id, countersignId, stepStatus, countersignStatus, expiredTime, stepExtension);
-//            }
-//            stepBox.Steps.AddRange(subSteps);
-//            await _workflowStepRepository.AddRangeAsync(subSteps, cancellationToken);
-
-//            //create traces
-//            foreach (var step in subSteps)
-//            {
-//                await CreateTraceAsync(workflow, step, traceStatus, cancellationToken);
-//            }
-//        }
-
-//        /// <summary>
-//        /// 查询未完成节点
-//        /// </summary>
-//        /// <param name="stepBoxes"></param>
-//        /// <param name="orgCode"></param>
-//        /// <param name="userId"></param>
-//        /// <returns></returns>
-//        private (WorkflowStep, WorkflowStep) GetUnCompleteStep(List<WorkflowStep> stepBoxes, string orgCode, string userId)
-//        {
-//            var (stepBox, step) = GetStep(stepBoxes, orgCode, userId, d => d != EWorkflowStepStatus.Handled);
-//            if (step == null)
-//                throw new UserFriendlyException(
-//                    $"未找到对应节点, workflowId: {stepBoxes.FirstOrDefault()?.WorkflowId} orgCode:{orgCode}, userId: {userId}",
-//                    "未找到对应节点");
-//            return (stepBox, step);
-//        }
-
-//        private (WorkflowStep, WorkflowStep) GetUnCompleteStepOrDefault(List<WorkflowStep> stepBoxes, string orgCode, string userId) =>
-//            GetStep(stepBoxes, orgCode, userId, d => d != EWorkflowStepStatus.Handled);
-
-//        private (WorkflowStep, WorkflowStep) GetStep(List<WorkflowStep> stepBoxes, string orgCode, string userId, Func<EWorkflowStepStatus, bool> predicate)
-//        {
-//            if (!stepBoxes.Any()) throw new UserFriendlyException("该流程中暂无节点");
-//            foreach (var stepBox in stepBoxes)
-//            {
-//                foreach (var step in stepBox.Steps)
-//                {
-//                    if (predicate(step.Status) && (step.Handlers.Any(d => d.Key == orgCode) || step.Handlers.Any(d => d.Key == userId)))
-//                        return (stepBox, step);
-//                }
-//            }
-
-//            return new();
-//        }
-
-//        private WorkflowStep CreateStepBox(string workflowId, StepDefine stepDefine, string prevStepBoxId)
-//        {
-//            var stepBox = _mapper.Map<WorkflowStep>(stepDefine);
-//            stepBox.WorkflowId = workflowId;
-//            stepBox.PreviousStepId = prevStepBoxId;
-//            stepBox.NextStepCode = string.Empty;
-//            stepBox.Opinion = string.Empty;
-//            stepBox.CountersignStartStepCode = stepDefine.CountersignStartStepCode;
-//            stepBox.CountersignEndStepCode = stepDefine.CountersignEndStepCode;
-//            return stepBox;
-//        }
-
-//        private List<WorkflowStep> CreateSubSteps(
-//            bool isPrevStartCountersign,
-//            WorkflowStep stepBox,
-//            List<Kv> handlers,
-//            string nextStepCode,
-//            string? nextMainHandler,
-//            string? prevStepId,
-//            string? countersignId,
-//            EWorkflowStepStatus stepStatus,
-//            ECountersignPosition countersignPosition,
-//            DateTime expiredTime,
-//            StepExtension extension)
-//        {
-//            if (countersignPosition is ECountersignPosition.None && !string.IsNullOrEmpty(countersignId))
-//                throw UserFriendlyException.SameMessage("非法参数");
-//            if (countersignPosition is not ECountersignPosition.None && string.IsNullOrEmpty(countersignId))
-//                throw UserFriendlyException.SameMessage("非法参数");
-
-//            //依据是否发起会签创建step,发起会签表示一个handler创建一个step,未发起会签表示多人处理同一个节点,只创建一个step
-//            var steps = new List<WorkflowStep>();
-//            if (isPrevStartCountersign)
-//            {
-//                foreach (var handler in handlers)
-//                {
-//                    var step = CreateSubStep(stepBox, new List<Kv> { handler }, nextStepCode, nextMainHandler,
-//                        prevStepId, countersignId, stepStatus, countersignPosition, expiredTime, extension);
-
-//                    steps.Add(step);
-//                }
-//            }
-//            else
-//            {
-//                var step = CreateSubStep(stepBox, handlers, nextStepCode, nextMainHandler,
-//                    prevStepId, countersignId, stepStatus, countersignPosition, expiredTime, extension);
-
-//                steps.Add(step);
-//            }
-
-//            return steps;
-//        }
-
-//        private WorkflowStep CreateSubStep(
-//            WorkflowStep stepBox,
-//            List<Kv> handlers,
-//            string nextStepCode,
-//            string? nextMainHandler,
-//            string? prevStepId,
-//            string? countersignId,
-//            EWorkflowStepStatus stepStatus,
-//            ECountersignPosition countersignPosition,
-//            DateTime expiredTime,
-//            StepExtension extension)
-//        {
-//            if (!handlers.Any())
-//                throw new UserFriendlyException("非法参数");
-//            var step = _mapper.Map<WorkflowStep>(stepBox);
-//            var handlerIds = handlers.Select(d => d.Key).ToList();
-//            var isMain = handlers.Count == 1 || (handlers.Count > 1 || handlerIds.First() == nextMainHandler);
-
-//            step.ParentId = stepBox.Id;
-//            step.Handlers = handlers;
-//            step.NextStepCode = step.StepType is EStepType.End ? string.Empty : nextStepCode;
-//            step.IsMain = isMain;
-//            step.PreviousStepId = prevStepId;
-//            step.CountersignId = countersignId;
-//            step.Status = stepStatus;
-//            step.CountersignPosition = countersignPosition;
-//            step.ExpiredTime = expiredTime;
-//            step.TimeLimit = GetTimeLimit("");//todo 过期时间
-//            step.Extension = extension;
-
-//            return step;
-//        }
-
-//        /// <summary>
-//        /// 依据配置生成过期时间
-//        /// </summary>
-//        /// <returns></returns>
-//        private DateTime CalculateExpiredTime(string defineCode, DateTime? time = null)
-//        {
-//            time ??= DateTime.Now;
-//            var config = GetConfig(defineCode);
-//            return time.Value.AddDays(config.Days);
-//        }
-
-//        private string GetTimeLimit(string defineCode)
-//        {
-//            return GetConfig(defineCode).Description;
-//        }
-
-//        private ConfigIncludeDescriptionAndTime GetConfig(string defineCode)
-//        {
-//            return new ConfigIncludeDescriptionAndTime
-//            {
-//                Days = 7,
-//                Description = "7个工作日"//todo 依据配置生成, Think about 工作日
-//            };
-//        }
-
-//        #endregion
-
-//    }
-
-//    public class ConfigIncludeDescriptionAndTime
-//    {
-//        public int Days { get; set; }
-//        public string Description { get; set; }
-//    }
-//}

+ 2 - 0
src/Hotline/FlowEngine/Workflows/WorkflowStep.cs

@@ -200,6 +200,8 @@ public class WorkflowStep : StepBasicEntity
         AcceptorOrgAreaName = null;
         AcceptTime = null;
 
+        IsStartCountersign = false;
+
         NextSteps.ForEach(d => d.Selected = false);
     }
 

+ 0 - 200
src/Hotline/FlowEngine/Workflows/WorkflowStep1.cs

@@ -1,200 +0,0 @@
-//using Hotline.Share.Dtos;
-//using Hotline.Share.Enums.FlowEngine;
-//using SqlSugar;
-
-//namespace Hotline.FlowEngine.Workflows;
-
-//public class WorkflowStep1 : StepBasicEntity
-//{
-//    [SugarColumn(ColumnDataType = "json", IsJson = true)]
-//    public List<StepSimple> NextSteps { get; set; }
-
-//    /// <summary>
-//    /// 前一级节点Id(stepBox此字段为上级stepBoxId,step为上级stepId),汇总节点无此字段(因可能有多个上级来源)
-//    /// </summary>
-//    [SugarColumn(IsNullable = true)]
-//    public string? PreviousId { get; set; }
-
-//    /// <summary>
-//    /// 主办
-//    /// </summary>
-//    public bool IsMain { get; set; }
-
-//    /// <summary>
-//    /// 节点办理状态
-//    /// </summary>
-//    public EWorkflowStepStatus Status { get; set; } = EWorkflowStepStatus.WaitForAccept;
-
-//    /// <summary>
-//    /// stepBox此字段无效,记录stepBox与其下subSteps关系
-//    /// </summary>
-//    public string? ParentId { get; set; }
-
-//    [SugarColumn(IsIgnore = true)]
-//    public List<WorkflowStep> Steps { get; set; } = new();
-
-//    #region 会签
-
-//    /// <summary>
-//    /// 发起会签生成会签Id(不发起会签节点无此字段)
-//    /// </summary>
-//    [SugarColumn(IsNullable = true)]
-//    public string? StartCountersignId { get; set; }
-
-//    /// <summary>
-//    /// 会签id
-//    /// </summary>
-//    [SugarColumn(IsNullable = true)]
-//    public string? CountersignId { get; set; }
-
-//    /// <summary>
-//    /// 当前节点发起的会签是否已结束,冗余(未发起会签的节点此字段为null)
-//    /// <remarks>
-//    /// 发起的会签结束以后更新,如果有子会签,则所有子会签都结束以后才会更新此字段
-//    /// </remarks>¡
-//    /// </summary>
-//    public bool? IsStartedCountersignComplete { get; set; }
-
-//    /// <summary>
-//    /// 节点会签状态
-//    /// </summary>
-//    public ECountersignPosition CountersignPosition { get; set; }
-
-//    /// <summary>
-//    /// 发起会签节点code(冗余)
-//    /// </summary>
-//    [SugarColumn(IsNullable = true)]
-//    public string? CountersignStartStepCode { get; set; }
-
-//    /// <summary>
-//    /// 会签汇总节点code(冗余)
-//    /// </summary>
-//    [SugarColumn(IsNullable = true)]
-//    public string? CountersignEndStepCode { get; set; }
-
-//    /// <summary>
-//    /// 是否处于会签流程中
-//    /// </summary>
-//    [SugarColumn(IsIgnore = true)]
-//    public bool IsInCountersign => !string.IsNullOrEmpty(CountersignId);
-
-//    /// <summary>
-//    /// 是否发起过会签
-//    /// </summary>
-//    [SugarColumn(IsIgnore = true)]
-//    public bool HasStartedCountersign => !string.IsNullOrEmpty(StartCountersignId);
-
-//    #endregion
-
-//    #region Method
-
-//    /// <summary>
-//    /// 接办
-//    /// </summary>
-//    /// <param name="userId"></param>
-//    /// <param name="userName"></param>
-//    public void Accept(string userId, string? userName, string orgCode, string? orgName)
-//    {
-//        AcceptorId = userId;
-//        AcceptorName = userName;
-//        AcceptTime = DateTime.Now;
-//        AcceptorOrgId = orgCode;
-//        AcceptorOrgName = orgName;
-//        Status = EWorkflowStepStatus.WaitForHandle;
-//    }
-
-//    /// <summary>
-//    /// 节点办理完成
-//    /// </summary>
-//    /// <param name="userId"></param>
-//    /// <param name="userName"></param>
-//    /// <param name="orgCode"></param>
-//    /// <param name="orgName"></param>
-//    public void Complete(string userId, string? userName, string orgCode, string? orgName, string? areaCode, string? areaName, string nextStepCode)
-//    {
-//        HandlerId = userId;
-//        HandlerName = userName;
-//        HandlerOrgId = orgCode;
-//        HandlerOrgName = orgName;
-//        HandlerOrgAreaCode = areaCode;
-//        HandlerOrgAreaName = areaName;
-//        HandleTime = DateTime.Now;
-//        Status = EWorkflowStepStatus.Handled;
-
-//        if (StepType is not EStepType.End or EStepType.Start)
-//            NextSteps.First(d => d.Code == nextStepCode).Selected = true;
-//    }
-
-//    /// <summary>
-//    /// 检查stepBox状态,如果子节点全都办理,则stepBox办理完成
-//    /// </summary>
-//    public void CheckStepBoxStatusAndUpdate()
-//    {
-//        if (Status is not EWorkflowStepStatus.Handled && Steps.All(d => d.Status is EWorkflowStepStatus.Handled))
-//        {
-//            Status = EWorkflowStepStatus.Handled;
-//            HandleTime = Steps.Max(d => d.HandleTime);
-//        }
-//    }
-
-//    /// <summary>
-//    /// 会签结束
-//    /// </summary>
-//    public void CountersignComplete() => IsStartedCountersignComplete = true;
-
-//    /// <summary>
-//    /// 开启会签
-//    /// </summary>
-//    public void StartCountersign(string startCountersignId)
-//    {
-//        StartCountersignId = startCountersignId;
-//        IsStartedCountersignComplete = false;
-//    }
-
-//    /// <summary>
-//    /// step设置为可接办状态
-//    /// </summary>
-//    public void SetAssigned() => Status = EWorkflowStepStatus.WaitForAccept;
-
-//    /// <summary>
-//    /// 依据当前节点获取下一节点会签状态
-//    /// </summary>
-//    /// <returns></returns>
-//    public ECountersignPosition GetNextStepCountersignStatus()
-//    {
-//        if (HasStartedCountersign)
-//        {
-//            return ECountersignPosition.Inner;
-//        }
-//        return IsInCountersign ? ECountersignPosition.Outer : ECountersignPosition.None;
-//    }
-
-//    /// <summary>
-//    /// 重置节点,只清除办理痕迹(退回场景,将上一级节点重置等待重新办理)
-//    /// </summary>
-//    public void Reset()
-//    {
-//        SetAssigned();
-//        NextHandlers = new();
-//        NextMainHandler = null;
-//        NextStepCode = string.Empty;
-//        IsSms = default;
-//        Opinion = string.Empty;
-//        Additions = new();
-
-//        HandlerId = null;
-//        HandlerName = null;
-//        HandlerOrgId = null;
-//        HandlerOrgName = null;
-//        HandleTime = null;
-
-//        AcceptorId = null;
-//        AcceptorName = null;
-//        AcceptorOrgId = null;
-//        AcceptorOrgName = null;
-//        AcceptTime = null;
-//    }
-
-//    #endregion
-
-//}