using APT.BaseData.Domain.ApiModel;
using APT.BaseData.Domain.Entities;
using APT.BaseData.Domain.Enums;
using APT.BaseData.Domain.IServices;
using APT.Infrastructure.Core;
using APT.BaseData.Domain.Entities.FM;
using APT.BaseData.Domain.IServices.FM;
using APT.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using APT.Infrastructure.Api;
namespace APT.BaseData.Services.Services.FM
{
    public partial class PFFlowService : CommonService, IPFFlowService
    {
        IFMUserService UserService { get; set; }
        public PFFlowService(IRepository repository, IFMUserService userService)
               : base(repository)
        {
            this.UserService = userService;
        }
        #region 流程处理API
        /// 
        /// 检查自动送审(直接保存数据)
        /// 
        /// 
        /// 
        /// 实体类型 参考PFCodeRuleType
        public void SendFlowAndCommit(T entity, int entityType, string schemeCode, Action action) where T : MesEntityBase, new()
        {
            if (entity == null)
                throw new Exception("无效的实体");
            //if (entity.FLOW_SEND_STATUS == (int)PPFlowSendStatusEnum.已送审) return;
            //var dbEntity = this.AddAndGetEntity(entity);
            if (entity.FLOW_STATUS == (int)PPFlowStatusEnum.审核中 || entity.FLOW_STATUS == (int)PPFlowStatusEnum.审核通过)
                return;
            var tmpScheme = this.GetEntity(t => t.SchemeCode == schemeCode
             && t.Disabled == (int)PPFlowSchemeDisabledEnum.启用);
            if (tmpScheme != null)
            {
                entity.FLOW_STATUS = (int)PPFlowStatusEnum.未送审;
                if (tmpScheme.ActiveAutoSend == 1)//自动送审
                {
                    SendFlowParam param = new SendFlowParam();
                    param.EntityId = entity.ID;
                    param.EntityType = entityType;
                    param.FlowSchemeId = tmpScheme.ID;
                    SendFlow(param,tmpScheme,entity, action);
                }
            }
            else if (entity.FLOW_STATUS == (int)PPFlowStatusEnum.未送审)
            {
                entity.FLOW_STATUS = (int)PPFlowStatusEnum.审核通过;
                this.UpdateEntity(entity);
            }
        }
        /// 
        /// 检查自动送审(直接保存数据)
        /// 
        /// 
        /// 
        /// 实体类型 参考PFCodeRuleType
        public void AddAndSendFlow(T entity, int entityType) where T : MesEntityBase, new()
        {
            if (entity == null)
                throw new Exception("无效的实体");
            //if (entity.FLOW_SEND_STATUS == (int)PPFlowSendStatusEnum.已送审) return;
            //var dbEntity = this.AddAndGetEntity(entity);
            if (entity.FORM_ID == null)
                throw new Exception("实体表单不允许为空");
            this.UpdateEntity(entity);
            if (entity.FLOW_STATUS == (int)PPFlowStatusEnum.审核中 || entity.FLOW_STATUS == (int)PPFlowStatusEnum.审核通过)
                return;
            var tmpScheme = this.GetEntities(t => t.FrmId == entity.FORM_ID
             && t.Disabled == (int)PPFlowSchemeDisabledEnum.启用).OrderByDescending(t => t.SortCode).FirstOrDefault();
            if (tmpScheme != null)
            {
                entity.FLOW_STATUS = (int)PPFlowStatusEnum.未送审;
                if (tmpScheme.ActiveAutoSend == 1)//自动送审
                {
                    SendFlowParam param = new SendFlowParam();
                    param.EntityId = entity.ID;
                    param.EntityType = entityType;
                    param.FlowSchemeId = tmpScheme.ID;
                    SendFlow(param);
                }
            }
            else if (entity.FLOW_STATUS == (int)PPFlowStatusEnum.未送审)
            {
                entity.FLOW_STATUS = (int)PPFlowStatusEnum.审核通过;
                this.UpdateEntity(entity);
            }
        }
        /// 
        /// 检查自动送审(直接保存数据)
        /// 
        /// 
        /// 
        /// 实体类型 参考PFCodeRuleType
        public void CheckAndSendFlow(Guid id, int entityType) where T : MesEntityBase, new()
        {
            CheckAndSendFlow(id, entityType, string.Empty, string.Empty);
        }
        /// 
        /// 检查自动送审(直接保存数据)
        /// 
        /// 
        /// 
        /// 实体类型 参考PFCodeRuleType
        /// 
        /// 
        public void CheckAndSendFlow(Guid id, int entityType, string userId, string userName) where T : MesEntityBase, new()
        {
            if (id == Guid.Empty) return;
            //var flowSchemeService = ServiceUtils.GetCommonService();
            //var entityService = ServiceUtils.GetCommonService();
            T entity = this.GetEntity(id);// entityService.Get(id);
            if (entity == null)
                throw new Exception("无效的实体");
            if (entity.FLOW_SEND_STATUS == (int)PPFlowSendStatusEnum.已送审) return;
            if (entity.FORM_ID == null)
                throw new Exception("实体表单不允许为空");
            var tmpScheme = this.GetEntities(t => t.FrmId == entity.FORM_ID
             && t.Disabled == (int)PPFlowSchemeDisabledEnum.启用).OrderByDescending(t => t.SortCode).FirstOrDefault();
            if (tmpScheme != null)
            {
                entity.FLOW_STATUS = (int)PPFlowStatusEnum.未送审;
                this.UpdateEntity(entity);
                if (tmpScheme.ActiveAutoSend == 1)//自动送审
                {
                    SendFlowParam param = new SendFlowParam();
                    param.EntityId = id;
                    param.FlowSchemeId = tmpScheme.ID;
                    param.UserId = userId;
                    param.EntityType = entityType;
                    param.UserName = userName;
                    SendFlow(param);
                }
            }
            else if (entity.FLOW_STATUS == (int)PPFlowStatusEnum.未送审)
            {
                entity.FLOW_STATUS = (int)PPFlowStatusEnum.审核通过;
                this.UpdateEntity(entity);
            }
        }
        /// 
        /// 检查自动送审(未保存数据)
        /// 
        /// 
        /// 
        /// 实体类型 参考PFCodeRuleType
        /// 
        public SendFlowResult CheckAndSendFlow(T entity, int entityType) where T : MesEntityBase, new()
        {
            if (entity.FLOW_SEND_STATUS == (int)PPFlowSendStatusEnum.已送审) return null;
            if (entity.FORM_ID == null)
                throw new Exception("实体表单不允许为空");
            //	var flowSchemeService = ServiceUtils.GetCommonService();
            SendFlowResult result = null;
            var tmpScheme = this.GetEntities(t => t.FrmId == entity.FORM_ID
           && t.Disabled == (int)PPFlowSchemeDisabledEnum.启用).OrderByDescending(t => t.SortCode).FirstOrDefault();
            if (tmpScheme != null)
            {
                entity.FLOW_STATUS = (int)PPFlowStatusEnum.未送审;
                if (tmpScheme.ActiveAutoSend == 1)//自动送审
                {
                    SendFlowEntityParam param = new SendFlowEntityParam();
                    param.Entity = entity;
                    param.FlowScheme = tmpScheme;
                    param.EntityType = entityType;
                    result = SendFlow(param);
                }
            }
            else if (entity.FLOW_STATUS == (int)PPFlowStatusEnum.未送审)
            {
                entity.FLOW_STATUS = (int)PPFlowStatusEnum.审核通过;
            }
            return result;
        }
        /// 
        /// 送审(直接保存数据)
        /// 
        /// 实体ID
        /// 实体类型 参考PFCodeRuleType
        /// 
        public void SendFlow(Guid id, int entityType) where T : MesEntityBase, new()
        {
            SendFlow(id, entityType, string.Empty, string.Empty);
        }
        /// 
        /// 送审(直接保存数据)
        /// 
        /// 
        /// 实体ID
        /// 实体类型 参考PFCodeRuleType
        /// 
        /// 
        public void SendFlow(Guid id, int entityType, string userId, string userName) where T : MesEntityBase, new()
        {
            if (id == Guid.Empty) return;
            //	var flowSchemeService = ServiceUtils.GetCommonService();
            //	var entityService = ServiceUtils.GetCommonService();
            T entity = this.GetEntity(id);
            if (entity == null)
                throw new Exception("无效的实体");
            if (entity.FLOW_SEND_STATUS == (int)PPFlowSendStatusEnum.已送审) return;
            if (entity.FORM_ID == null)
                throw new Exception("实体表单不允许为空");
            var tmpScheme = this.GetEntities(t => t.FrmId == entity.FORM_ID
           && t.Disabled == (int)PPFlowSchemeDisabledEnum.启用).OrderByDescending(t => t.SortCode).FirstOrDefault();
            if (tmpScheme != null)
            {
                entity.FLOW_STATUS = (int)PPFlowStatusEnum.未送审;
                this.UpdateEntity(entity);
                SendFlowParam param = new SendFlowParam();
                param.EntityId = id;
                param.FlowSchemeId = tmpScheme.ID;
                param.UserId = userId;
                param.UserName = userName;
                param.EntityType = entityType;
                SendFlow(param);
            }
            else if (entity.FLOW_STATUS == (int)PPFlowStatusEnum.未送审)
            {
                entity.FLOW_STATUS = (int)PPFlowStatusEnum.审核通过;
                this.UpdateEntity(entity);
            }
        }
        public SendFlowResult SendFlow(SendFlowParam param, T_PF_FLOW_SCHEME flowScheme, T entity, Action action = null) where T : MesEntityBase, new()
        {
            //var flowSchemeService = ServiceUtils.GetCommonService();
            //var entityService = ServiceUtils.GetCommonService();
            //var flowInstanceService = ServiceUtils.GetCommonService();
            //var flowInstanceOperationHistoryService = ServiceUtils.GetCommonService();
            //var flowInstanceTransitionHistoryService = ServiceUtils.GetCommonService();
            var codeRuleService = APT.Infrastructure.Api.ServiceLocator.Instance.GetService();
            T_PF_FLOW_INSTANCE flowInstance = null;
            //flowInstance = this.GetEntity(i=>i.InstanceSchemeId==flowScheme.ID);
            var orgId = param.OrgId == null ? entity.ORG_ID : param.OrgId;
            SystemCodeFilter filter = new SystemCodeFilter();
            filter.CodeType = (int)PFCodeRuleType.审批流编码;
            filter.Count = 1;
            filter.OrgId = orgId;
            var code = codeRuleService.NewGenSerial(filter);
            var result = DoSendFlow(code, orgId, param.CustomName, param.Description,
                flowScheme, entity, param.EntityType, flowInstance, param.UserId, param.UserName);
            UnifiedCommit(() =>
            {
                if (action != null)
                    action();
                this.UpdateEntityNoCommit(entity);
                if (result.FlowInstance != null)
                {
                    if (flowInstance == null)
                        this.AddEntityNoCommit(result.FlowInstance);
                    else
                        this.UpdateEntityNoCommit(result.FlowInstance);
                }
                if (result.FlowInstanceOperationHistory != null)
                    this.AddEntityNoCommit(result.FlowInstanceOperationHistory);
                if (result.FlowInstanceTransitionHistory != null)
                    this.AddEntityNoCommit(result.FlowInstanceTransitionHistory);
            });
            return result;
        }
        /// 
        /// 送审
        /// 
        /// 
        public SendFlowResult SendFlow(SendFlowParam param, Action action = null) where T : MesEntityBase, new()
        {
            //var flowSchemeService = ServiceUtils.GetCommonService();
            //var entityService = ServiceUtils.GetCommonService();
            //var flowInstanceService = ServiceUtils.GetCommonService();
            //var flowInstanceOperationHistoryService = ServiceUtils.GetCommonService();
            //var flowInstanceTransitionHistoryService = ServiceUtils.GetCommonService();
            var codeRuleService = APT.Infrastructure.Api.ServiceLocator.Instance.GetService();
            T entity = null;
            if (param.EntityId != null)
            {
                entity = this.GetEntity(param.EntityId.ToString());
                if (entity == null)
                    throw new Exception("无效的实体");
                if (entity.FLOW_SEND_STATUS == (int)PPFlowSendStatusEnum.已送审) return null;
            }
            else
                throw new Exception("参数异常");
            if (entity.FORM_ID == null)
                throw new Exception("实体表单不允许为空");
            if (entity != null && entity.FORM_ID != null && param.FlowSchemeId == Guid.Empty)
            {
                var tmpScheme = this.GetEntities(t => t.FrmId == entity.FORM_ID
               && t.Disabled == (int)PPFlowSchemeDisabledEnum.启用).OrderByDescending(t => t.SortCode).FirstOrDefault();
                if (tmpScheme != null)
                    param.FlowSchemeId = tmpScheme.ID;
            }
            if (param.FlowSchemeId == Guid.Empty)
                throw new Exception("参数异常");
            var flowScheme = this.GetEntity(param.FlowSchemeId.ToString());
            if (flowScheme == null)
                throw new Exception("无效的流程模板");
            T_PF_FLOW_INSTANCE flowInstance = null;
            if (entity.FLOW_ID != null)
                flowInstance = this.GetEntity(entity.FLOW_ID.Value.ToString());
            var orgId = param.OrgId == null ? entity.ORG_ID : param.OrgId;
            SystemCodeFilter filter = new SystemCodeFilter();
            filter.CodeType = (int)PFCodeRuleType.审批流编码;
            filter.Count = 1;
            filter.OrgId = orgId;
            var code = codeRuleService.NewGenSerial(filter);
            var result = DoSendFlow(code, orgId, param.CustomName, param.Description, flowScheme, entity, param.EntityType, flowInstance, param.UserId, param.UserName);
            UnifiedCommit(() =>
            {
                if (action != null)
                    action();
                this.UpdateEntityNoCommit(entity);
                if (result.FlowInstance != null)
                {
                    if (flowInstance == null)
                        this.AddEntityNoCommit(result.FlowInstance);
                    else
                        this.UpdateEntityNoCommit(result.FlowInstance);
                }
                if (result.FlowInstanceOperationHistory != null)
                    this.AddEntityNoCommit(result.FlowInstanceOperationHistory);
                if (result.FlowInstanceTransitionHistory != null)
                    this.AddEntityNoCommit(result.FlowInstanceTransitionHistory);
            });
            return result;
        }
        /// 
        /// 送审
        /// 
        /// 
        /// 
        /// 
        public SendFlowResult SendFlow(SendFlowEntityParam param) where T : MesEntityBase, new()
        {
            if (param.Entity == null || param.FlowScheme == null)
                throw new Exception("参数异常");
            //var flowSchemeService = ServiceUtils.GetCommonService();
            //var entityService = ServiceUtils.GetCommonService();
            //var flowInstanceService = ServiceUtils.GetCommonService();
            //var flowInstanceOperationHistoryService = ServiceUtils.GetCommonService();
            //var flowInstanceTransitionHistoryService = ServiceUtils.GetCommonService();
            var codeRuleService = APT.Infrastructure.Api.ServiceLocator.Instance.GetService();
            var orgId = param.OrgId == null || param.Entity != null ? param.Entity.ORG_ID : param.OrgId;
            var code = param.FlowCode;
            if (string.IsNullOrEmpty(code))
            {
                SystemCodeFilter filter = new SystemCodeFilter();
                filter.CodeType = (int)PFCodeRuleType.审批流编码;
                filter.Count = 1;
                filter.OrgId = orgId;
                code = codeRuleService.NewGenSerial(filter);
            }
            T_PF_FLOW_INSTANCE flowInstance = null;
            if (param.Entity.FLOW_ID != null)
                flowInstance = this.GetEntity(param.Entity.FLOW_ID.Value);
            return DoSendFlow(code, orgId, param.CustomName, param.Description, param.FlowScheme, param.Entity, param.EntityType, flowInstance, param.UserId, param.UserName);
        }
        /// 
        /// 审核流程
        /// 
        /// 
        /// 
        public void PermitFlow(PermitFlowParam param) where T : MesEntityBase, new()
        {
            if (param.FlowId == Guid.Empty)
                throw new Exception("参数异常");
            //var entityService = ServiceUtils.GetCommonService();
            //var flowInstanceOperationHistoryService = ServiceUtils.GetCommonService();
            //var flowInstanceTransitionHistoryService = ServiceUtils.GetCommonService(); 
            var flowInstance = this.GetEntity(param.FlowId);
            if (flowInstance == null)
                throw new Exception("无效流程");
            var entity = flowInstance.EntityId == null ? null : this.GetEntity(flowInstance.EntityId.Value);
            if (entity == null)
                throw new Exception("无效的实体");
            var curUserId = param.UserId;
            var curUserName = param.UserName;
            if (string.IsNullOrEmpty(curUserId))
            {
                curUserId = Infrastructure.Api.AppContext.CurrentSession.UserId;
                curUserName = this.GetEntityByRedis(curUserId, flowInstance.ORG_ID ?? Guid.Empty)?.NAME;
            }
            PPFlowPermitStatusEnum permitStatusEnum = (PPFlowPermitStatusEnum)param.PermitStatus;
            if (permitStatusEnum == PPFlowPermitStatusEnum.同意 || permitStatusEnum == PPFlowPermitStatusEnum.不同意)
            {
                T_PF_FLOW_INSTANCE_TRANS_HIS flowInstanceTransitionHistory = null;
                T_PF_FLOW_INSTANCE_OPER_HIS flowInstanceOperationHistory = new T_PF_FLOW_INSTANCE_OPER_HIS
                {
                    InstanceId = flowInstance.ID,
                    CreateUserId = curUserId,
                    CreateUserName = curUserName,
                    CreateDate = DateTime.Now,
                    ORG_ID = flowInstance.ORG_ID
                };//操作记录
                FlowRuntime wfruntime = new FlowRuntime(flowInstance, entity);
                var tag = new Tag
                {
                    UserName = curUserName,
                    UserId = curUserId,
                    Description = param.Description
                };
                #region 会签
                if (flowInstance.ActivityType == 0)//当前节点是会签节点
                {
                    tag.Taged = 1;
                    wfruntime.MakeTagNode(wfruntime.runtimeModel.currentNodeId, tag);//标记会签节点状态
                    string verificationNodeId = ""; //寻找当前登陆用户可审核的节点Id
                    List nodelist = wfruntime.GetCountersigningNodeIdList(wfruntime.runtimeModel.currentNodeId);
                    StringBuilder sb = new StringBuilder();
                    foreach (string item in nodelist)
                    {
                        var makerList = GetMakerList(wfruntime.runtimeModel.nodes[item], flowInstance.ORG_ID);
                        if (makerList == "-1") continue;
                        if (makerList == "1")
                            throw new Exception("会签节点的审核者不能为所有人,请查看流程设计是否有问题!");
                        if (string.IsNullOrEmpty(verificationNodeId))
                        {
                            if (makerList.Split(',').Any(one => curUserId == one))
                            {
                                verificationNodeId = item;
                            }
                            else
                            {
                                sb.Append(makerList);
                                sb.Append(',');
                            }
                        }
                        else
                        {
                            sb.Append(makerList);
                            sb.Append(',');
                        }
                    }
                    if (!string.IsNullOrEmpty(verificationNodeId))
                    {
                        if (permitStatusEnum == PPFlowPermitStatusEnum.同意)
                        {
                            tag.Taged = 1;
                            flowInstanceOperationHistory.Content = "【" + wfruntime.runtimeModel.nodes[verificationNodeId].name + "】【" + DateTime.Now.ToString("yyyy-MM-dd HH:mm") + "】同意,备注:" + param.Description;
                        }
                        else
                        {
                            tag.Taged = -1;
                            flowInstanceOperationHistory.Content = "【" + wfruntime.runtimeModel.nodes[verificationNodeId].name + "】【" + DateTime.Now.ToString("yyyy-MM-dd HH:mm") + "】不同意,备注:" + param.Description;
                        }
                        wfruntime.MakeTagNode(verificationNodeId, tag);//标记审核节点状态
                        string confluenceres = wfruntime.NodeConfluence(verificationNodeId, tag);
                        switch (confluenceres)
                        {
                            case "-1"://不通过
                                flowInstance.OrderStatus = (int)PFFlowInstanceOrderStatusEnum.完成但不同意;
                                flowInstance.MakerList = "-1";
                                break;
                            case "1"://等待,当前节点还是会签开始节点,不跳转
                                if (sb.Length > 0)
                                    sb.Length--;
                                flowInstance.MakerList = sb.ToString();
                                break;
                            default://通过
                                flowInstance.PreviousId = flowInstance.ActivityId;
                                flowInstance.ActivityId = wfruntime.runtimeModel.nextNodeId;
                                flowInstance.ActivityType = wfruntime.runtimeModel.nextNodeType;//-1无法运行,0会签开始,1会签结束,2一般节点,4流程运行结束
                                flowInstance.ActivityName = wfruntime.runtimeModel.nextNode.name;
                                flowInstance.OrderStatus = (wfruntime.runtimeModel.nextNodeType
                                    == 4 ? (int)PFFlowInstanceOrderStatusEnum.完成并同意 : (int)PFFlowInstanceOrderStatusEnum.未完成);
                                flowInstance.MakerList = (wfruntime.runtimeModel.nextNodeType == (int)PFFlowInstanceOrderStatusEnum.被驳 ? "" : GetMakerList(wfruntime, flowInstance.ORG_ID));//当前节点可执行的人信息
                                flowInstance.ActivityEditable = wfruntime.GetNodePermitEditable(flowInstance.ActivityId);
                                #region 流转记录
                                flowInstanceTransitionHistory = new T_PF_FLOW_INSTANCE_TRANS_HIS
                                {
                                    InstanceId = flowInstance.ID,
                                    CreateUserId = curUserId,
                                    CreateUserName = curUserName,
                                    FromNodeId = wfruntime.runtimeModel.currentNodeId,
                                    FromNodeName = wfruntime.runtimeModel.currentNode.name,
                                    FromNodeType = wfruntime.runtimeModel.currentNodeType,
                                    ToNodeId = wfruntime.runtimeModel.nextNodeId,
                                    ToNodeName = wfruntime.runtimeModel.nextNode.name,
                                    ToNodeType = wfruntime.runtimeModel.nextNodeType,
                                    IsFinish = wfruntime.runtimeModel.nextNodeType == 4 ? 1 : 0,
                                    TransitionSate = 0,
                                    ORG_ID = flowInstance.ORG_ID
                                };
                                #endregion
                                break;
                        }
                        if (wfruntime.runtimeModel.nextNodeType == 4)//结束节点
                        {
                            tag.Taged = 1;
                            wfruntime.MakeTagNode(wfruntime.runtimeModel.nextNodeId, tag);
                        }
                    }
                    else
                    {
                        return;
                        //throw (new Exception("审核异常,找不到审核节点"));
                    }
                }
                #endregion
                #region 一般审核
                else//一般审核
                {
                    if (flowInstance.MakerList != "1" && !flowInstance.MakerList.Contains(curUserId)) return;
                    if (permitStatusEnum == PPFlowPermitStatusEnum.同意)
                    {
                        tag.Taged = 1;
                        wfruntime.MakeTagNode(wfruntime.runtimeModel.currentNodeId, tag);
                        if (wfruntime.runtimeModel.nextNodeType == 4)//结束节点
                        {
                            wfruntime.MakeTagNode(wfruntime.runtimeModel.nextNodeId, tag);
                        }
                        flowInstance.PreviousId = flowInstance.ActivityId;
                        flowInstance.ActivityId = wfruntime.runtimeModel.nextNodeId;
                        flowInstance.ActivityType = wfruntime.runtimeModel.nextNodeType;
                        flowInstance.ActivityName = wfruntime.runtimeModel.nextNode.name;
                        flowInstance.MakerList = wfruntime.runtimeModel.nextNodeType == (int)PFFlowInstanceOrderStatusEnum.完成并同意 ? "" : GetMakerList(wfruntime, flowInstance.ORG_ID);//当前节点可执行的人信息
                        flowInstance.OrderStatus = (wfruntime.runtimeModel.nextNodeType == 4 ?
                            (int)PFFlowInstanceOrderStatusEnum.完成并同意 : (int)PFFlowInstanceOrderStatusEnum.未完成);
                        flowInstance.ActivityEditable = wfruntime.GetNodePermitEditable(flowInstance.ActivityId);
                        if (wfruntime.runtimeModel.nextNodeType == 0)//会签重置下个节点的审批状态
                        {
                            List _nodelist = wfruntime.GetCountersigningNodeIdList(wfruntime.runtimeModel.nextNodeId);
                            wfruntime.ClearTagNode(wfruntime.runtimeModel.nextNodeId);
                            foreach (string item in _nodelist)
                            {
                                wfruntime.ClearTagNode(item);
                            }
                        }
                        #region 流转记录
                        flowInstanceTransitionHistory = new T_PF_FLOW_INSTANCE_TRANS_HIS
                        {
                            InstanceId = flowInstance.ID,
                            CreateUserId = curUserId,
                            CreateUserName = curUserName,
                            FromNodeId = wfruntime.runtimeModel.currentNodeId,
                            FromNodeName = wfruntime.runtimeModel.currentNode.name,
                            FromNodeType = wfruntime.runtimeModel.currentNodeType,
                            ToNodeId = wfruntime.runtimeModel.nextNodeId,
                            ToNodeName = wfruntime.runtimeModel.nextNode.name,
                            ToNodeType = wfruntime.runtimeModel.nextNodeType,
                            IsFinish = wfruntime.runtimeModel.nextNodeType == 4 ? 1 : 0,
                            TransitionSate = 0,
                            ORG_ID = flowInstance.ORG_ID
                        };
                        #endregion
                        flowInstanceOperationHistory.Content = "【" + wfruntime.runtimeModel.currentNode.name
                            + "】【" + DateTime.Now.ToString("yyyy-MM-dd HH:mm") + "】同意,备注:" + param.Description;
                    }
                    else
                    {
                        flowInstance.OrderStatus = (int)PFFlowInstanceOrderStatusEnum.完成但不同意; //表示该节点不同意
                        tag.Taged = -1;
                        wfruntime.MakeTagNode(wfruntime.runtimeModel.currentNodeId, tag);
                        flowInstanceOperationHistory.Content = "【"
                            + wfruntime.runtimeModel.currentNode.name + "】【"
                            + DateTime.Now.ToString("yyyy-MM-dd HH:mm") + "】不同意,备注:"
                            + param.Description;
                    }
                }
                #endregion
                if (flowInstance.OrderStatus == (int)PFFlowInstanceOrderStatusEnum.完成并同意)
                {
                    entity.FLOW_STATUS = (int)PPFlowStatusEnum.审核通过;
                }
                else if (flowInstance.OrderStatus == (int)PFFlowInstanceOrderStatusEnum.完成但不同意)
                {
                    entity.FLOW_STATUS = (int)PPFlowStatusEnum.审核失败;
                }
                else
                {
                    entity.FLOW_STATUS = (int)PPFlowStatusEnum.审核中;
                }
                flowInstance.EntityFlowStatus = entity.FLOW_STATUS;
                flowInstance.SchemeContent = JsonHelper.Serialize(wfruntime.runtimeModel.schemeContentJson);
                UnifiedCommit(() =>
                {
                    this.UpdateEntityNoCommit(flowInstance);
                    this.UpdateEntityNoCommit(entity);
                    this.AddEntityNoCommit(flowInstanceOperationHistory);
                    if (flowInstanceTransitionHistory != null)
                        this.AddEntityNoCommit(flowInstanceTransitionHistory);
                });
            }
            else
            {
                if (flowInstance.MakerList != "1" && !flowInstance.MakerList.Contains(curUserId)) return;
                T_PF_FLOW_INSTANCE_TRANS_HIS flowInstanceTransitionHistory = null;
                T_PF_FLOW_INSTANCE_OPER_HIS flowInstanceOperationHistory = null;
                FlowRuntime wfruntime = new FlowRuntime(flowInstance, entity);
                string resnode = "";
                if (string.IsNullOrEmpty(param.NodeRejectStep))
                {
                    resnode = wfruntime.RejectNode();
                }
                else
                {
                    resnode = param.NodeRejectStep;
                }
                var tag = new Tag
                {
                    Description = param.Description,
                    Taged = 0,
                    UserId = curUserId,
                    UserName = curUserName,
                };
                wfruntime.MakeTagNode(wfruntime.runtimeModel.currentNodeId, tag);
                foreach (dynamic item in wfruntime.runtimeModel.schemeContentJson.nodes)
                {
                    if (item.id == wfruntime.runtimeModel.currentNodeId)
                    {
                        item.setInfo.ConfluenceOk = 0;
                    }
                }
                //wfruntime.runtimeModel.schemeContentJson.nodes[wfruntime.runtimeModel.currentNodeId].setInfo.ConfluenceOk = 0;//会签重置为0
                flowInstance.OrderStatus = (int)PFFlowInstanceOrderStatusEnum.被驳;//4表示驳回(需要申请者重新提交表单)
                if (resnode != "")
                {
                    wfruntime.MakeTagNode(resnode, tag);
                    flowInstance.PreviousId = flowInstance.ActivityId;
                    flowInstance.ActivityId = resnode;
                    flowInstance.ActivityType = wfruntime.GetNodeType(resnode);
                    flowInstance.ActivityName = wfruntime.runtimeModel.nodes[resnode].name;
                    flowInstance.MakerList = GetMakerList(wfruntime, wfruntime.runtimeModel.nodes[resnode], flowInstance.ORG_ID);//当前节点可执行的人信息
                    flowInstance.ActivityEditable = wfruntime.GetNodePermitEditable(flowInstance.ActivityId);
                    #region 流转记录
                    flowInstanceTransitionHistory = new T_PF_FLOW_INSTANCE_TRANS_HIS
                    {
                        InstanceId = flowInstance.ID,
                        CreateUserId = curUserId,
                        CreateUserName = curUserName,
                        FromNodeId = wfruntime.runtimeModel.currentNodeId,
                        FromNodeName = wfruntime.runtimeModel.currentNode.name,
                        FromNodeType = wfruntime.runtimeModel.currentNodeType,
                        ToNodeId = resnode,
                        ToNodeName = wfruntime.runtimeModel.nodes[resnode].name,
                        ToNodeType = wfruntime.GetNodeType(resnode),
                        IsFinish = wfruntime.GetNodeType(resnode) == 4 ? 1 : 0,
                        TransitionSate = 1,
                        ORG_ID = flowInstance.ORG_ID
                    };
                    #endregion
                }
                flowInstanceOperationHistory = new T_PF_FLOW_INSTANCE_OPER_HIS
                {
                    InstanceId = flowInstance.ID,
                    CreateUserId = curUserId,
                    CreateUserName = curUserName,
                    CreateDate = DateTime.Now,
                    Content = "【"
                              + wfruntime.runtimeModel.currentNode.name
                              + "】【" + DateTime.Now.ToString("yyyy-MM-dd HH:mm") + "】驳回,备注:"
                              + param.Description,
                    ORG_ID = flowInstance.ORG_ID
                };
                entity.FLOW_STATUS = (int)PPFlowStatusEnum.驳回;
                if (wfruntime.GetNodeType(flowInstance.ActivityId) == 3)//开始节点
                {
                    //entity.FLOW_STATUS = (int)PPFlowStatusEnum.未送审;
                    entity.FLOW_SEND_STATUS = (int)PPFlowSendStatusEnum.未送审;
                }
                flowInstance.SchemeContent = JsonHelper.Serialize(wfruntime.runtimeModel.schemeContentJson);
                UnifiedCommit(() =>
                {
                    this.UpdateEntityNoCommit(flowInstance);
                    this.UpdateEntityNoCommit(entity);
                    this.AddEntityNoCommit(flowInstanceOperationHistory);
                    if (flowInstanceTransitionHistory != null)
                        this.AddEntityNoCommit(flowInstanceTransitionHistory);
                });
            }
        }
        /// 
        /// 审核流程
        /// 
        /// 
        public void PermitFlowSimple(PermitFlowParam param)
        {
            var flowInstance = this.GetEntity(param.FlowId);
            if (flowInstance == null)
                throw new Exception("无效流程");
            if (string.IsNullOrEmpty(flowInstance.EntityTypeFullName))
                throw new Exception("数据异常");
            MethodInfo methodInfo = this.GetType().GetMethod("PermitFlow", BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static);
            try
            {
                var types = new Type[] { APT.Infrastructure.Core.Refctor.ReflectHelper.FindTypeInCurrentDomain(flowInstance.EntityTypeFullName) };
                var method = methodInfo.MakeGenericMethod(types);
                method.Invoke(this, new object[] { param });
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null)
                    throw ex.InnerException;
                throw ex;
            }
        }
        public PagedResultDto QueryFlowInstance(KeywordPageFilter pageFilter)
        {
            PagedResultDto list = null;
            PPFlowQueryFlowInstanceTypeEnum type = pageFilter.Parameter1 == null ? PPFlowQueryFlowInstanceTypeEnum.待办事项 :
                (PPFlowQueryFlowInstanceTypeEnum)Convert.ToInt32(pageFilter.Parameter1);
            var userId = pageFilter.Keyword;
            if (string.IsNullOrEmpty(userId))
                userId = Infrastructure.Api.AppContext.CurrentSession.UserId;
            if (string.IsNullOrEmpty(userId))
                throw new Exception("人员不允许为空");
            if (type == PPFlowQueryFlowInstanceTypeEnum.待办事项)   //待办事项
            {
                list = this.GetOrderPageEntities(u => u.MakerList == "1" || u.MakerList.Contains(userId), pageFilter);
            }
            else if (type == PPFlowQueryFlowInstanceTypeEnum.已办事项)  //已办事项(即我参与过的流程)
            {
                //var flowInstanceService = ServiceUtils.GetCommonService();
                //var instances = this.GetOrderPageEntities(u => u.CreateUserId == userId)
                //    .Select(u => u.InstanceId).Distinct().ToList();
                list = this.GetOrderPageEntities(u => u.TransitionHistorys.Any(x => x.CreateUserId == userId), pageFilter);
            }
            else  //我的流程
            {
                list = this.GetOrderPageEntities(u => u.CreateUserId == userId, pageFilter);
            }
            List userIdList = new List();
            Dictionary> itemUserId = new Dictionary>();
            foreach (var item in list.Items)
            {
                if (item.MakerList != "1" && item.MakerList != "-1" && !string.IsNullOrEmpty(item.MakerList))
                {
                    var usrId = item.MakerList.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                        .Select(i => new Guid(i)).ToList();
                    itemUserId.Add(item.ID, usrId);
                    userIdList.AddRange(usrId);
                }
            }
            var users = this.GetEntities(x => userIdList.Contains(x.ID));
            foreach (var item in list.Items)
            {
                if (!string.IsNullOrEmpty(item.MakerList))
                {
                    if (item.MakerList == "1")
                        item.Vir_MakerName = "全部人员";
                    else if (item.MakerList != "-1")
                    {
                        //var useList = this.GetEntities(t => item.MakerList.Contains(t.ID.ToString())).ToList();
                        if (itemUserId.ContainsKey(item.ID))
                        {
                            var theUser = users.Where(i => itemUserId[item.ID].Contains(i.ID)).Select(i => i.NAME).ToArray();
                            item.Vir_MakerName = string.Join(',', theUser);
                        }
                        //用户
                    }
                }
            }
            return list;
        }
        /// 获取流程模板/summary>
        /// 
        /// 
        public FlowSchemeResponse GetFlowScheme(KeywordFilter filter)
        {
            if (string.IsNullOrEmpty(filter.Keyword))
                throw new Exception("参数异常");
            //var flowSchemeService = ServiceUtils.GetCommonService();
            FlowSchemeResponse response = new FlowSchemeResponse();
            var flowScheme = this.GetEntity(filter.Keyword);
            response.Scheme = flowScheme;
            if (flowScheme.FrmId != null && flowScheme.FrmId != Guid.Empty)
                response.Form = GetForm(flowScheme.FrmId.Value);
            return response;
        }
        /// 
        /// 获取流程
        /// 
        /// 
        /// 
        public FlowResponse GetFlow(KeywordFilter filter)
        {
            if (string.IsNullOrEmpty(filter.Keyword))
                throw new Exception("参数异常");
            //var flowInstanceService = ServiceUtils.GetCommonService();
            //var flowInstanceOperationHistoryService = ServiceUtils.GetCommonService();
            FlowResponse response = new FlowResponse();
            var flowInstance = this.GetEntity(new Guid(filter.Keyword));
            if (flowInstance.EntityId != null && flowInstance.EntityId != Guid.Empty && !string.IsNullOrEmpty(flowInstance.EntityTypeFullName))
            {
                //var comService = typeof(APT.Infrastructure.Core.CommonService);
                var methodInfo = this.GetType().GetMethod("GetMyEntity", BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static);
                var entityType = APT.Infrastructure.Core.Refctor.ReflectHelper.FindTypeInCurrentDomain(flowInstance.EntityTypeFullName);
                response.Entity = methodInfo.MakeGenericMethod(new Type[] { entityType }).Invoke(this, new object[] { flowInstance.EntityId.Value });
            }
            response.Flow = flowInstance;
            if (flowInstance.FrmId != null && flowInstance.FrmId != Guid.Empty)
                response.Form = GetForm(flowInstance.FrmId.Value);
            response.OperationHistorys = this.GetEntities(t => t.InstanceId == flowInstance.ID).OrderBy(t => t.CREATE_TIME).ToList();
            return response;
        }
        #endregion
        public T GetMyEntity(Guid id) where T : MesEntityBase, new()
        {
            return this.GetEntity(id.ToString());
        }
        public T GetEntity(Guid id) where T : MesEntityBase, new()
        {
            return this.GetEntity(id.ToString());
        }
        private T_PF_FORM GetForm(Guid id)
        {
            return this.GetEntity(id.ToString());
        }
        /// 
        /// 寻找该节点执行人
        /// 
        /// 
        /// 
        private string GetMakerList(FlowRuntime wfruntime, Guid? orgId)
        {
            if (wfruntime.runtimeModel.nextNodeId == "-1")
            {
                throw (new Exception("无法寻找到下一个节点"));
            }
            return GetMakerList(wfruntime, wfruntime.runtimeModel.nodes[wfruntime.runtimeModel.nextNodeId], orgId);
        }
        private string ArrayToString(dynamic data, string Str)
        {
            if (data == null) return Str;
            string resStr = Str;
            foreach (var item in data)
            {
                if (resStr != "")
                {
                    resStr += ",";
                }
                resStr += item.ToString();
            }
            return resStr;
        }
        private string GetMakerList(FlowNode node, Guid? orgId)
        {
            string makerList = "";
            if (node.setInfo == null)
            {
                makerList = "-1";
            }
            else
            {
                if (node.setInfo.NodeDesignate == FlowSetInfo.ALL_USER)//所有成员
                {
                    makerList = "1";
                }
                else if (node.setInfo.NodeDesignate == FlowSetInfo.SPECIAL_USER)//指定成员
                {
                    makerList = ArrayToString(node.setInfo.NodeDesignateData.users, makerList);
                    if (makerList == "")
                    {
                        makerList = "-1";
                    }
                }
                else if (node.setInfo.NodeDesignate == FlowSetInfo.SPECIAL_ROLE)  //指定角色
                {
                    var users = this.UserService.GetUsersByRoles(node.setInfo.NodeDesignateData.roles, orgId).Select(t => t.ID).ToList();
                    makerList = ArrayToString(users, makerList);
                    if (makerList == "")
                    {
                        makerList = "-1";
                    }
                }
            }
            return makerList;
        }
        /// 
        /// 寻找该节点执行人
        /// 
        /// 
        /// 
        private string GetMakerList(FlowRuntime wfruntime, FlowNode node, Guid? orgId)
        {
            if (node == null)
                return "-1";
            var type = wfruntime.GetNodeType(node.id);
            string makerList = "";
            if (type == 0)//如果是会签节点
            {
                List _nodelist = wfruntime.GetCountersigningNodeIdList(node.id);
                string _makerList = "";
                foreach (string item in _nodelist)
                {
                    _makerList = GetMakerList(wfruntime.runtimeModel.nodes[item], orgId);
                    if (_makerList == "-1")
                    {
                        throw (new Exception("无法寻找到会签节点的审核者,请查看流程设计是否有问题!"));
                    }
                    if (_makerList == "1")
                    {
                        throw (new Exception("会签节点的审核者不能为所有人,请查看流程设计是否有问题!"));
                    }
                    if (makerList != "")
                    {
                        makerList += ",";
                    }
                    makerList += _makerList;
                }
            }
            else if (type == 3 || type == 4)//开始节点  结束节点
            {
                makerList = "-1";
            }
            else
            {
                makerList = GetMakerList(node, orgId);
                if (makerList == "-1")
                {
                    throw (new Exception("无法寻找到节点的审核者,请查看流程设计是否有问题!"));
                }
            }
            return makerList;
        }
        private string GetTypeFullName(Type type)
        {
            string basetypeFullName = string.Empty;
            if (string.Compare(type.Namespace, "System.Data.Entity.DynamicProxies", true) == 0)
                basetypeFullName = type.BaseType.FullName;
            else
                basetypeFullName = type.FullName;
            string moduleName = string.Empty;
            int dllIndex = basetypeFullName.IndexOf("APT.ECM.Domain", StringComparison.OrdinalIgnoreCase);
            if (dllIndex > -1)
                moduleName = "APT.ECM.Domain";
            else
                moduleName = " APT.ECM.Domain";
            return basetypeFullName + "," + moduleName;
        }
        private void CheckSendFlow(T_PF_FLOW_SCHEME flowScheme, T obj) where T : MesEntityBase, new()
        {
            if (obj.FLOW_SEND_STATUS == (int)PPFlowSendStatusEnum.已送审)
                throw new Exception("该资料已送审过了,不允许重新送审");
        }
        private SendFlowResult DoSendFlow(string code, Guid? orgId, string customName, string description, T_PF_FLOW_SCHEME flowScheme, T entity, int entityType, T_PF_FLOW_INSTANCE flowInstance, string userId, string userName) where T : MesEntityBase, new()
        {
            if (string.IsNullOrEmpty(code))
                throw new Exception("流程代码不允许为空");
            if (flowScheme == null)
                throw new Exception("无效流程模板");
            if (entity == null)
                throw new Exception("无效实体");
            SendFlowResult result = new SendFlowResult();
            if (flowScheme.Disabled == (int)PPFlowSchemeDisabledEnum.不启用)
            {
                entity.FLOW_SEND_STATUS = (int)PPFlowSendStatusEnum.已送审;
                entity.FLOW_STATUS = (int)PPFlowStatusEnum.审核通过;
                result.Entity = entity;
                return result;
            }
            var curUserId = string.IsNullOrEmpty(userId) ? Infrastructure.Api.AppContext.CurrentSession.UserId : userId;
            var typFullName = entity.GetType().Name;
            var user = this.GetEntityByRedis(curUserId, orgId ?? Guid.Empty);
            bool isCreateFlowInstance = false;
            if (flowInstance == null)
            {
                isCreateFlowInstance = true;
                string entityCode = string.Empty;
                Type type = typeof(T);
                PropertyInfo propertyInfo = type.GetProperty("CODE"); //获取指定名称的属性
                if (propertyInfo != null)
                {
                    object tmp = propertyInfo.GetValue(entity, null); //获取属性值
                    if (tmp != null)
                        entityCode = tmp.ToString();
                }
                flowInstance = new T_PF_FLOW_INSTANCE();
                flowInstance.FrmId = flowScheme.PermitFrmId != null ? flowScheme.PermitFrmId : flowScheme.FrmId;//优先取审核时的表单ID
                flowInstance.SchemeContent = flowScheme.SchemeContent;
                flowInstance.InstanceSchemeId = flowScheme.ID;
                flowInstance.Code = code;
                flowInstance.CustomName = string.IsNullOrEmpty(customName) ? DateTime.Now.ToString("yyyy-MM-dd") + "_" + flowScheme.SchemeName + "_" + entityCode : customName;
                flowInstance.Description = description == null ? string.Empty : description;
                flowInstance.EntityTypeFullName = typFullName;
                flowInstance.EntityId = entity.ID;
                flowInstance.ORG_ID = orgId;
                flowInstance.EntityType = entityType;
                flowInstance.CreateUserName = user?.NAME;
            }
            else//重新送审时清空
            {
                flowInstance.ActivityId = string.Empty;
                flowInstance.ActivityType = 0;
                flowInstance.ActivityName = string.Empty;
                flowInstance.PreviousId = string.Empty;
                flowInstance.MakerList = string.Empty;
                flowInstance.OrderStatus = 0;
                flowInstance.ActivityEditable = 0;
            }
            //创建运行实例
            var wfruntime = new FlowRuntime(flowInstance, entity);
            #region 根据运行实例改变当前节点状态
            flowInstance.ActivityId = wfruntime.runtimeModel.nextNodeId;
            flowInstance.ActivityType = wfruntime.GetNextNodeType();//-1无法运行,0会签开始,1会签结束,2一般节点,4流程运行结束
            flowInstance.ActivityName = wfruntime.runtimeModel.nextNode.name;
            flowInstance.PreviousId = wfruntime.runtimeModel.currentNodeId;
            flowInstance.CreateUserId = curUserId;
            flowInstance.CreateUserName = user?.NAME;
            flowInstance.MakerList = (wfruntime.GetNextNodeType() != 4 ? GetMakerList(wfruntime, flowInstance.ORG_ID) : "");//当前节点可执行的人信息
            flowInstance.OrderStatus = (wfruntime.GetNextNodeType() == 4 ?
                            (int)PFFlowInstanceOrderStatusEnum.完成并同意 : (int)PFFlowInstanceOrderStatusEnum.未完成);
            flowInstance.ActivityEditable = wfruntime.GetNodePermitEditable(flowInstance.ActivityId);
            #endregion
            #region 实体状态更新
            entity.FLOW_SEND_STATUS = (int)PPFlowSendStatusEnum.已送审;
            entity.FLOW_STATUS = (int)PPFlowStatusEnum.审核中;
            entity.FLOW_ID = flowInstance.ID;
            #endregion
            flowInstance.EntityFlowStatus = entity.FLOW_STATUS;
            #region 流程操作记录
            T_PF_FLOW_INSTANCE_OPER_HIS processOperationHistoryEntity = new T_PF_FLOW_INSTANCE_OPER_HIS
            {
                InstanceId = flowInstance.ID,
                CreateUserId = curUserId,
                CreateUserName = user?.NAME,
                CreateDate = DateTime.Now,
                ORG_ID = orgId,
                Content = isCreateFlowInstance ? ("【创建】"
                          + user?.NAME
                          + "创建了一个流程进程【"
                          + flowInstance.Code + "/"
                          + flowInstance.CustomName + "】") : ("【送审】"
                          + user?.NAME
                          + "送审了一个流程进程【"
                          + flowInstance.Code + "/"
                          + flowInstance.CustomName + "】")
            };
            #endregion
            #region 流转记录
            T_PF_FLOW_INSTANCE_TRANS_HIS processTransitionHistoryEntity = new T_PF_FLOW_INSTANCE_TRANS_HIS
            {
                InstanceId = flowInstance.ID,
                FromNodeId = wfruntime.runtimeModel.currentNodeId,
                FromNodeName = wfruntime.runtimeModel.currentNode.name,
                FromNodeType = wfruntime.runtimeModel.currentNodeType,
                ToNodeId = wfruntime.runtimeModel.nextNodeId,
                ToNodeName = wfruntime.runtimeModel.nextNode.name,
                ToNodeType = wfruntime.runtimeModel.nextNodeType,
                IsFinish = wfruntime.runtimeModel.nextNodeType == 4 ? 1 : 0,
                TransitionSate = 0,
                CreateUserId = curUserId,
                CreateUserName = user?.NAME,
                ORG_ID = orgId,
            };
            #endregion
            result.Entity = entity;
            result.FlowInstance = flowInstance;
            result.FlowInstanceOperationHistory = processOperationHistoryEntity;
            result.FlowInstanceTransitionHistory = processTransitionHistoryEntity;
            return result;
        }
    }
}