namespace APT.PF.WebApi.Controllers.Api
{
    using APT.Infrastructure.Core;
    using Microsoft.AspNetCore.Mvc;
    using System.Collections.Generic;
    using APT.Utility;
    using APT.Infrastructure.Api;
    using APT.BaseData.Domain.ApiModel.PF;
    using APT.BaseData.Domain.Entities;
    using APT.BaseData.Domain.Enums.PF;
    using System.Linq;
    using System;
    using APT.BaseData.Domain.IServices.FM;
    using APT.MS.Domain.Enums;
    using System.Dynamic;
    using System.Reflection;
    using APT.BaseData.Domain.Entities.PF;
    using APT.BaseData.Domain.Entities.FM;
    using System.Linq.Expressions;
    using APT.MS.Domain.Entities.BS;
    using APT.BaseData.Domain.Enums;
    using APT.BaseData.Domain.IServices;
    using APT.MS.Domain.Entities.HM;
    using Newtonsoft.Json;
    using NPOI.Util;
    using System.Data;
    using NPOI.SS.Formula.Functions;
    using APT.MS.Domain.Entities.SC;
    using APT.Infrastructure.EF;
    using APT.BaseData.Services.DomainServices;
    using APT.BaseData.Services.Services.FM;
    using APT.BaseData.Services.Sys;

    [Route("api/PF/PFApprove")]
    public partial class ApproveController : AuthorizeApiController<T_PF_APPROVE>
    {
        IFMNotificationTaskService NotificationTaskService { get; set; }
        IPFSysLogService SysLogService { get; set; }

        IRepository Repository { get; set; }
        IPFCodeRuleService CodeRuleService { get; set; }

        IFMDepartmentService DepartmentService { get; set; }
        IFMUserService UserService { get; set; }

        public ApproveController(IFMNotificationTaskService notificationTaskService, IPFSysLogService sysLogService, IRepository repository, IPFCodeRuleService codeRuleService, IFMDepartmentService departmentService, IFMUserService userService)
        {
            NotificationTaskService = notificationTaskService;
            SysLogService = sysLogService;
            Repository = repository;
            codeRuleService = CodeRuleService;
            DepartmentService = departmentService;
            UserService = userService;
        }
        /// <summary>
        /// 更新或新增数据
        /// </summary>
        /// <param name="entity">对象实体</param>
        /// <returns></returns>
        [HttpPost, Route("FullUpdate")]
        public JsonActionResult<bool> FullUpdate([FromBody] T_PF_APPROVE entity)
        {
            return SafeExecute<bool>(() =>
            {
                var detail = entity.Nav_ApproveDetails;
                entity.Nav_ApproveDetails = null;
                UnifiedCommit(() =>
                {
                    this.UpdateEntityNoCommit(entity);
                    if (detail != null)
                        this.BantchSaveEntityNoCommit(detail);
                });
                return true;
            });
        }



        /// <summary>
        /// 审批单据
        /// </summary>
        /// <param name="entity">对象实体</param>
        /// <returns></returns>
        [HttpPost, Route("Submit")]
        public JsonActionResult<string> Submit([FromBody] T_PF_APPROVE entity)
        {
            return base.SafeExecute(() =>
            {
                var ret = string.Empty;
                var dbApprove = this.GetEntity<T_PF_APPROVE>(entity.ID.ToString(), false, "Nav_ApproveDetails");
                if (dbApprove == null)
                    this.ThrowError("020027");
                if (dbApprove.APPROVE_STATUS != (int)ApproveStatus.Doing)
                    this.ThrowError("020028");
                var node = dbApprove.Nav_ApproveDetails.FirstOrDefault(i => i.ID == entity.CurrentNode.ID);
                if (!node.IS_CURRENT)
                    this.ThrowError("020030");
                //查询消息表
                var task = this.GetEntity<T_FM_NOTIFICATION_TASK>(i => i.SOURCE_DATA_ID == entity.ID && i.USER_ID == node.APPROVE_USER_ID
                && i.NOTICE_STATUS == FMNoticeStatusEnum.未处理.GetInt(), false);
                if (task != null)
                {
                    task.NOTICE_STATUS = FMNoticeStatusEnum.正常已办.GetInt();
                    task.TASK_DT = DateTime.Now;
                    if (DateTime.Now > task.TASK_ENDDT)
                        task.NOTICE_STATUS = FMNoticeStatusEnum.超期办理.GetInt();
                }
                //修改节点状态
                node.NODE_APPROVE_TIME = DateTime.Now;
                node.NODE_APPROVE_STATUS = entity.CurrentNode.NODE_APPROVE_STATUS;
                node.IS_CURRENT = false;
                node.CONTEXT = entity.CurrentNode.CONTEXT;

                //Type dbTypeEnd = null;//反射类
                //MethodInfo methodInfoEnd = null;//反射方法

                //更新审批单据状态
                if (node.NODE_APPROVE_STATUS == (int)NodeApproveStatus.Reject)//驳回
                {
                    //驳回时状态改为驳回，并通知申请人重新提交
                    dbApprove.APPROVE_STATUS = ApproveStatus.Reject.GetInt();
                    var details = dbApprove.Nav_ApproveDetails;
                    dbApprove.Nav_ApproveDetails = null;
                    details.ForEach(i => i.Nav_Approve = null);
                    List<Guid> userIds = new List<Guid>();
                    userIds.Add((Guid)dbApprove.CREATER_ID);
                    //消息通知并修改状态
                    NotificationTaskService.SendNotificationTask(entity.NAME + "已被驳回,请重新新建表单提交审核",
                        entity.ID, APT.Infrastructure.Api.AppContext.CurrentSession.OrgId, userIds,
                        DateTime.Now, DateTime.Now.AddHours(24), (int)FMNoticeTypeEnum.消息, "PF119", () =>
                        {
                            if (task != null)
                                this.UpdateEntityNoCommit(task);
                            this.UpdateEntityNoCommit(dbApprove);
                            this.BantchUpdateEntityNoCommit(details);
                        });
                    return ret;
                }
                else if (node.NODE_APPROVE_STATUS == (int)NodeApproveStatus.Done)
                {
                    //判断下一个节点是否包含 本节点的人
                    //如果是 并且 只有这个人  
                    // 继续判断下一个人节点 

                    #region    wyw 默认审批判断

                    bool isLast = false;
                    List<T_PF_APPROVE_DETAIL> Nav_ApproveDetails = dbApprove.Nav_ApproveDetails.ToList();
                    DoneLaterApproverDeal(node, node.APPROVE_USER_ID.Value, node.CONTEXT, node.NODE_APPROVE_STATUS, ref Nav_ApproveDetails, ref isLast);
                    dbApprove.Nav_ApproveDetails = Nav_ApproveDetails;//可能会有修改赋值过去

                    #endregion

                    //var lastNode = dbApprove.Nav_ApproveDetails.Where(i => i.NUM >= entity.CurrentNode.NUM && i.ID != entity.CurrentNode.ID && i.NODE_APPROVE_STATUS == (int)NodeApproveStatus.Doing);
                    //if (!lastNode.Any())

                    if (isLast)
                    {
                        dbApprove.APPROVE_STATUS = ApproveStatus.Done.GetInt();//完成
                        ret = dbApprove.CALLBACK_INTERFACE;

                        //if (ret == "SC/SCMtMeetingMinutes/MeetingMinutesBack")
                        //{
                        //    //不存在无参的构造函数所以实例化失败  ccy
                        //    var callBackInterface = APT.Infrastructure.Core.Refctor.ReflectHelper.FindTypeInCurrentDomain("PFApproveCallBackMTService");
                        //    MethodInfo callbackMethd = callBackInterface.GetMethod("MeetingMinutesBack", BindingFlags.Public | BindingFlags.Instance); 
                        //    var instance = Activator.CreateInstance(callBackInterface, Repository, CodeRuleService, NotificationTaskService, SysLogService, DepartmentService, UserService);
                        //    callbackMethd.Invoke(instance, new object[] { dbApprove.DATA_ID.ToString() });

                        //    //将方法写在此类也可以调用  wyw
                        //    //var callBackInterface1 = this.GetType();
                        //    //MethodInfo callbackMethd1 = callBackInterface1.GetMethod("MeetingMinutesBack", BindingFlags.Public | BindingFlags.Instance); // Error lies
                        //    //callbackMethd1.Invoke(this, new object[] { dbApprove.DATA_ID.ToString() });
                        //}

                        //查询审批的表单数据
                        var form = this.GetEntity<T_PF_FORM>(i => i.CODE == dbApprove.APPROVE_CODE, new BaseFilter(dbApprove.ORG_ID));
                        var tableName = form?.TABLE_NAME;
                        if (string.IsNullOrEmpty(tableName))
                        {
                            var formEdit = this.GetEntity<T_PF_PAGE_EDIT>(i => i.PAGE_FORM_ID == form.ID && i.PARENT_ID == null);
                            if (formEdit != null)
                            {
                                tableName = formEdit.EDIT_NAME;
                            }
                        }
                        if (!string.IsNullOrEmpty(tableName))
                        {
                            var dbType = APT.Infrastructure.Core.Refctor.ReflectHelper.FindTypeInCurrentDomain(tableName);
                            if (dbType != null)
                            {
                                MethodInfo methodInfo = this.GetType().GetMethod("GetMyEntity",
                 BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static);
                                var entity = methodInfo.MakeGenericMethod(new Type[] { dbType }).
                                         Invoke(this, new object[] { dbApprove.DATA_ID });
                                if (entity != null)
                                {
                                    var prop = dbType.GetProperty("FLOW_STATUS");
                                    if (prop != null)
                                    {
                                        prop.SetValue(entity, 2);
                                        MethodInfo methodInfoUpdate = this.GetType().GetMethod("UpdateMyEntityNoCommit",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static);
                                        var details = dbApprove.Nav_ApproveDetails;
                                        dbApprove.Nav_ApproveDetails = null;
                                        details.ForEach(i => i.Nav_Approve = null);
                                        UnifiedCommit(() =>
                                        {
                                            if (task != null)
                                                this.UpdateEntityNoCommit(task);
                                            this.UpdateEntityNoCommit(dbApprove);
                                            this.BantchUpdateEntityNoCommit(details);
                                            methodInfoUpdate.MakeGenericMethod(new Type[] { dbType }).
                                                 Invoke(this, new object[] { entity });
                                        });
                                        return ret;

                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        var next = dbApprove.Nav_ApproveDetails.Where(i => i.NUM == entity.CurrentNode.NUM && i.ID != entity.CurrentNode.ID && i.NODE_APPROVE_STATUS == (int)NodeApproveStatus.Doing);
                        if (next.Any())
                        {

                        }
                        else
                        {
                            //var nextNodes = dbApprove.Nav_ApproveDetails.Where(i => i.NUM > entity.CurrentNode.NUM);//wyw
                            var nextNodes = dbApprove.Nav_ApproveDetails.Where(i => i.NUM > entity.CurrentNode.NUM && i.NODE_APPROVE_STATUS == (int)NodeApproveStatus.Doing);
                            if (nextNodes.Any())
                            {
                                T_PF_APPROVE_DETAIL curentApprove = null;
                                GetApproveNodes(nextNodes.ToList(), ref curentApprove);
                                //所有节点均无审核人,直接归档
                                if (curentApprove == null)
                                {
                                    dbApprove.APPROVE_STATUS = ApproveStatus.Done.GetInt();//完成
                                    ret = dbApprove.CALLBACK_INTERFACE;
                                    //查询审批的表单数据
                                    var form = this.GetEntity<T_PF_FORM>(i => i.CODE == dbApprove.APPROVE_CODE, new BaseFilter(dbApprove.ORG_ID));
                                    var tableName = form?.TABLE_NAME;
                                    if (string.IsNullOrEmpty(tableName))
                                    {
                                        var formEdit = this.GetEntity<T_PF_PAGE_EDIT>(i => i.PAGE_FORM_ID == form.ID && i.PARENT_ID == null);
                                        if (formEdit != null)
                                        {
                                            tableName = formEdit.EDIT_NAME;
                                        }
                                    }
                                    if (!string.IsNullOrEmpty(tableName))
                                    {
                                        var dbType = APT.Infrastructure.Core.Refctor.ReflectHelper.FindTypeInCurrentDomain(tableName);
                                        if (dbType != null)
                                        {
                                            MethodInfo methodInfo = this.GetType().GetMethod("GetMyEntity",
                             BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static);
                                            var entity = methodInfo.MakeGenericMethod(new Type[] { dbType }).
                                                     Invoke(this, new object[] { dbApprove.DATA_ID });
                                            if (entity != null)
                                            {
                                                var prop = dbType.GetProperty("FLOW_STATUS");
                                                if (prop != null)
                                                {
                                                    prop.SetValue(entity, 2);
                                                    MethodInfo methodInfoUpdate = this.GetType().GetMethod("UpdateMyEntityNoCommit",
                            BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static);
                                                    var details = dbApprove.Nav_ApproveDetails;
                                                    dbApprove.Nav_ApproveDetails = null;
                                                    details.ForEach(i => i.Nav_Approve = null);
                                                    UnifiedCommit(() =>
                                                    {
                                                        if (task != null)
                                                            this.UpdateEntityNoCommit(task);
                                                        this.UpdateEntityNoCommit(dbApprove);
                                                        this.BantchUpdateEntityNoCommit(details);
                                                        methodInfoUpdate.MakeGenericMethod(new Type[] { dbType }).
                                                             Invoke(this, new object[] { entity });
                                                    });
                                                    return ret;

                                                }
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    var nextNode = nextNodes.Where(i => i.NUM == curentApprove.NUM && i.APPROVE_USER_ID != entity.CurrentNode.APPROVE_USER_ID);// && i.APPROVE_USER_ID != entity.CurrentNode.APPROVE_USER_ID 
                                    nextNode.ForEach(i => i.IS_CURRENT = true);


                                    List<Guid> userIds = new List<Guid>();
                                    userIds.AddRange(nextNode.Select(i => (Guid)i.APPROVE_USER_ID).ToArray());
                                    var details = dbApprove.Nav_ApproveDetails;
                                    details.ForEach(i => i.Nav_Approve = null);
                                    dbApprove.Nav_ApproveDetails = null;
                                    //var nextNodeName=nextNode.Select(i => i.NAME).FirstOrDefault();
                                    //消息通知并修改状态
                                    string NoticeTitle = entity.NAME;
                                    if (!entity.NAME.EndsWith("审批"))
                                    {
                                        NoticeTitle = NoticeTitle + "待审批";
                                    }
                                    var startTime = DateTime.Now;
                                    var endTime = DateTime.Now.AddHours(24);
                                    switch (entity.NAME)
                                    {
                                        case "作业任务识别表":
                                        case "作业任务识别分析表":
                                        case "一般任务分析表":
                                        case "关键任务分析表":
                                        case "作业许可分析表":
                                            endTime = Convert.ToDateTime(DateTime.Now.AddDays(2).ToString("D").ToString()).AddSeconds(-1);
                                            break;
                                        case "作业活动记录(一般作业)":
                                        case "关键许可工作票（无审批层级）":
                                        case "关键许可工作票（一级审批）":
                                        case "关键许可工作票（二级审批）":
                                        case "关键许可工作票（三级审批）":
                                        case "关键许可工作票（四级审批）":
                                            endTime = Convert.ToDateTime(DateTime.Now.AddDays(1).ToString("D").ToString()).AddSeconds(-1);
                                            break;
                                        default: break;
                                    }
                                    NotificationTaskService.SendNotificationTask(NoticeTitle,
                                        entity.ID, APT.Infrastructure.Api.AppContext.CurrentSession.OrgId, userIds,
                                        startTime, endTime, (int)FMNoticeTypeEnum.审批, "PF119", () =>
                                        {
                                            if (task != null)
                                                this.UpdateEntityNoCommit(task);
                                            this.UpdateEntityNoCommit(dbApprove);
                                            this.BantchUpdateEntityNoCommit(details);
                                        });
                                    return ret;
                                }
                            }
                            else
                            {

                            }
                        }
                    }
                }
                ChangeApproveStatus(dbApprove, task);//, dbTypeEnd, methodInfoEnd
                return ret;
            });
        }

        /// <summary>
        /// 审批通过  判断是否下一节点未本人 wyw
        /// </summary>
        /// <param name="currentNode"></param>
        /// <param name="OperateID"></param>
        /// <param name="CONTEXT"></param>
        /// <param name="NODE_APPROVE_STATUS"></param>
        /// <param name="Nav_ApproveDetails"></param>
        /// <param name="isLast"></param>
        private void DoneLaterApproverDeal(T_PF_APPROVE_DETAIL currentNode, Guid OperateID, string CONTEXT, int NODE_APPROVE_STATUS, ref List<T_PF_APPROVE_DETAIL> Nav_ApproveDetails, ref bool isLast)
        {
            if (NODE_APPROVE_STATUS != 10)
            {
                //审批不通过 
                return;
            }

            var detailDoing = Nav_ApproveDetails.FirstOrDefault(e => e.APPROVE_USER_ID.HasValue && e.NUM >= currentNode.NUM && e.NODE_APPROVE_STATUS == (int)NodeApproveStatus.Doing && e.ID != currentNode.ID);
            if (detailDoing == null)
            {
                //最后一个审批人了 
                isLast = true;
                return;
            }
            else
            {
                isLast = false;
            }
            if (!isLast)
            {
                //如果不是最后一个审批人 判断处理 下级审批人信息
                //同级 审批完了 下一级有他  默认审批
                var currentNumNode = Nav_ApproveDetails.FirstOrDefault(e => e.NUM == currentNode.NUM && e.ID != currentNode.ID && e.NODE_APPROVE_STATUS == (int)NodeApproveStatus.Doing);
                if (currentNumNode != null)
                {
                    //同级 还有未审批的 
                    return;
                }

                //同级没有未审批的人员信息 
                List<T_PF_APPROVE_DETAIL> listDoing = Nav_ApproveDetails.FindAll(e => e.NODE_APPROVE_STATUS == (int)NodeApproveStatus.Doing).OrderBy(e => e.NUM).ToList();
                if (listDoing != null && listDoing.Count > 0)
                {
                    //还有未审批的
                    List<T_PF_APPROVE_DETAIL> listDoingMin = listDoing.FindAll(e => e.NUM == listDoing[0].NUM);//最小未审批节点

                    T_PF_APPROVE_DETAIL detailLogin = listDoingMin.FirstOrDefault(e => e.APPROVE_USER_ID == OperateID);

                    if (detailLogin == null)
                    {
                        //下一个节点不是当前审批人
                        return;
                    }

                    //默认 审批
                    //detailLogin
                    detailLogin.NODE_APPROVE_TIME = DateTime.Now;
                    detailLogin.NODE_APPROVE_STATUS = (int)NodeApproveStatus.Done;
                    detailLogin.IS_CURRENT = false;
                    detailLogin.CONTEXT = CONTEXT;

                    if (listDoingMin.Count == 1)
                    {
                        DoneLaterApproverDeal(detailLogin, OperateID, CONTEXT, NODE_APPROVE_STATUS, ref Nav_ApproveDetails, ref isLast);
                    }
                }
            }
        }

        private void ChangeApproveStatus(T_PF_APPROVE dbApprove, T_FM_NOTIFICATION_TASK task)//, Type dbTypeEnd = null, MethodInfo methodInfoEnd = null
        {
            var details = dbApprove.Nav_ApproveDetails;
            dbApprove.Nav_ApproveDetails = null;
            details.ForEach(i => i.Nav_Approve = null);
            UnifiedCommit(() =>
            {
                if (task != null)
                    this.UpdateEntityNoCommit(task);
                this.UpdateEntityNoCommit(dbApprove);
                this.BantchUpdateEntityNoCommit(details);

                //if (methodInfoEnd != null)
                //    methodInfoEnd.MakeGenericMethod(new Type[] { dbTypeEnd }).Invoke(this, new object[] { dbApprove.DATA_ID.ToString() });
            });
        }

        public T GetMyEntity<T>(Guid id) where T : MesEntityBase, new()
        {
            return this.GetEntity<T>(id.ToString());
        }

        public T GetMyEntity2<T>(Expression<Func<T, bool>> expression) where T : MesEntityBase, new()
        {
            return GetEntity<T>(expression);
        }

        public void UpdateMyEntityNoCommit<T>(T entity) where T : MesEntityBase, new()
        {
            this.UpdateEntityNoCommit<T>(entity);
        }
        /// <summary>
        /// 转办
        /// </summary>
        /// <param name="keywordFilter">参数</param>
        /// <returns></returns>
        [HttpPost, Route("Complaint")]
        public JsonActionResult<bool> Complaint([FromBody] KeywordFilter keywordFilter)
        {
            return base.SafeExecute(() =>
            {
                if (string.IsNullOrEmpty(keywordFilter.Keyword))
                    this.ThrowError("020005");
                if (string.IsNullOrEmpty(keywordFilter.Parameter1))
                    this.ThrowError("020024");
                var dbApproveDetail = this.GetEntity<T_PF_APPROVE_DETAIL>(keywordFilter.Keyword, false, "Nav_Approve");
                if (dbApproveDetail == null)
                    this.ThrowError("020007");
                //查询消息表
                var task = this.GetEntity<T_FM_NOTIFICATION_TASK>(i => i.SOURCE_DATA_ID == dbApproveDetail.APPROVE_ID && i.USER_ID == dbApproveDetail.APPROVE_USER_ID
                && i.NOTICE_STATUS == FMNoticeStatusEnum.未处理.GetInt(), false);
                if (task != null)
                {
                    task.USER_ID = Guid.Parse(keywordFilter.Parameter1);
                    task.USER_NAME = this.GetEntity<T_FM_USER>(t => t.ID == task.USER_ID && t.ENABLE_STATUS == 0)?.NAME;
                }
                //修改当前审核人为转办人
                dbApproveDetail.APPROVE_USER_ID = Guid.Parse(keywordFilter.Parameter1);
                //添加转办记录
                T_PF_COMPLAINT_LOG complant = new T_PF_COMPLAINT_LOG();
                complant.ORG_ID = keywordFilter.OrgId;
                complant.APPROVE_DETAIL_ID = Guid.Parse(keywordFilter.Keyword);
                complant.COMPLAINT_USER_ID = Guid.Parse(keywordFilter.Parameter1);
                UnifiedCommit(() =>
                {
                    if (task != null)
                        this.UpdateEntityNoCommit(task);
                    if (dbApproveDetail != null)
                        this.UpdateEntityNoCommit(dbApproveDetail);
                    this.AddEntityNoCommit(complant);
                });
                return true;
            });
        }

        /// <summary>
        /// 根据数据id获取审核id
        /// </summary>
        /// <param name="keywordFilter">参数</param>
        /// <returns></returns>
        [HttpPost, Route("GetDataId")]
        public JsonActionResult<string> GetDataId([FromBody] KeywordFilter keywordFilter)
        {
            return SafeExecute<string>(() =>
            {
                Guid dataId = new Guid(keywordFilter.Keyword);
                bool isAPPROVEID = false;
                if (string.IsNullOrEmpty(keywordFilter.Keyword))
                    this.ThrowError("020005");
                if (!string.IsNullOrEmpty(keywordFilter.Parameter2))
                {
                    //以这种形式传参查看反射实现 一劳永逸
                    if (keywordFilter.Parameter2 == "T_BS_RISK_SUBMIT_NOTICE,RISK_SUBMIT_ID")
                    {
                        T_BS_RISK_SUBMIT_NOTICE modelNo = GetEntity<T_BS_RISK_SUBMIT_NOTICE>(e => e.RISK_SUBMIT_ID == dataId);
                        if (modelNo != null)
                            dataId = modelNo.ID;
                        else
                            return "";
                        //throw new Exception("未获取到审批流信息！");
                    }
                    else if (keywordFilter.Parameter2 == "T_BS_SAFE_CHECK,APPROVE_CHECKAUDIT_ID")
                    {
                        var T_BS_SAFE_CHECK = GetEntity<T_BS_SAFE_CHECK>(e => e.ID == dataId);
                        if (T_BS_SAFE_CHECK != null && T_BS_SAFE_CHECK.APPROVE_CHECKAUDIT_ID.HasValue)
                        {
                            dataId = T_BS_SAFE_CHECK.APPROVE_CHECKAUDIT_ID.Value;
                            isAPPROVEID = true;
                        }
                        else
                        {
                            dataId = Guid.Empty;
                        }
                    }
                }
                Expression<Func<T_PF_APPROVE, bool>> expression = e => e.DATA_ID == dataId;
                if (isAPPROVEID)
                {
                    expression = e => e.ID == dataId;
                }

                if (!string.IsNullOrEmpty(keywordFilter.Parameter1))
                {
                    expression = expression.And(e => e.PARAM == keywordFilter.Parameter1);
                }

                var orgId = APT.Infrastructure.Api.AppContext.CurrentSession.OrgId;
                var dbApprove = this.GetEntities<T_PF_APPROVE>(expression, new BaseFilter(keywordFilter.OrgId)).OrderByDescending(t => t.CREATE_TIME).FirstOrDefault();
                if (dbApprove == null)
                    return "";
                return dbApprove.ID.ToString();
            });
        }
        /// <summary>
        /// 更新状态为已阅
        /// </summary>
        /// <param name="dbApprove"></param>
        [HttpPost, Route("ChangeStatus")]
        public JsonActionResult<bool> ChangeStatus([FromBody] T_PF_APPROVE dbApprove)
        {
            return SafeExecute<bool>(() =>
            {
                //更新状态为已阅
                dbApprove.Nav_ApproveDetails = null;
                dbApprove.APPROVE_STATUS = (int)ApproveStatus.View;
                //查询消息表
                var task = this.GetEntity<T_FM_NOTIFICATION_TASK>(i => i.SOURCE_DATA_ID == dbApprove.ID && i.USER_ID == dbApprove.CREATER_ID
                && (i.NOTICE_STATUS == FMNoticeStatusEnum.未处理.GetInt() || i.NOTICE_STATUS == FMNoticeStatusEnum.超期办理.GetInt()), false);
                if (task != null)
                {
                    if (DateTime.Now > task.TASK_ENDDT)
                        task.NOTICE_STATUS = (int)FMNoticeStatusEnum.超期办理;
                    else
                        task.NOTICE_STATUS = (int)FMNoticeStatusEnum.正常已办;
                    //task.NOTICE_STATUS = FMNoticeStatusEnum.已阅.GetInt();
                    task.TASK_DT = DateTime.Now;
                }
                UnifiedCommit(() =>
                {
                    if (task != null)
                        this.UpdateEntityNoCommit(task);
                    this.UpdateEntityNoCommit(dbApprove);
                });
                return true;
            });
        }

        /// <summary>
        /// 获取下个审核节点、审核人
        /// </summary>
        /// <param name="approveDetails"></param>
        /// <param name="approveNode"></param>
        /// <returns></returns>
        static void GetApproveNodes(List<T_PF_APPROVE_DETAIL> approveDetails, ref T_PF_APPROVE_DETAIL approveNode)
        {
            if (approveDetails == null)
                return;
            var curentNode = approveDetails.FirstOrDefault(i => i.NUM == approveDetails.Min(x => x.NUM) && i.NODE_APPROVE_STATUS == (int)NodeApproveStatus.Doing);
            if (curentNode == null || curentNode.APPROVE_USER_ID == null)
            {
                approveDetails.Remove(curentNode);
                approveNode = null;
                if (!approveDetails.Any())
                    return;
                GetApproveNodes(approveDetails, ref approveNode);
            }
            else
            {
                approveNode = curentNode;
                return;
            }
        }
        /// <summary>
        /// 获得单条实体数据
        /// </summary>
        /// <param name="filter">过滤实体</param>
        /// <returns></returns>
        [HttpPost, Route("FullGet")]
        public JsonActionResult<T_PF_APPROVE> FullGet([FromBody] KeywordFilter filter)
        {
            var result = WitEntity(null, filter);
            if (result.Data != null)
            {
                if (result.Data.APPROVE_TEMP_ID != null)
                {
                    var approveTemp = this.GetEntity<T_PF_APPROVE_TEMP>(t => t.ID == result.Data.APPROVE_TEMP_ID);
                    if (approveTemp != null)
                        result.Data.REJECT_INTERFACE = approveTemp.REJECT_INTERFACE;
                }
                result.Data.Nav_ApproveDetails = result.Data.Nav_ApproveDetails.OrderBy(t => t.NUM).ThenBy(m => m.MODIFY_TIME).ToList();
            }
            return result;
        }

        /// <summary>
        /// 驳回单据
        /// </summary>
        /// <param name="entity">对象实体</param>
        /// <returns></returns>
        [HttpPost, Route("Reject")]
        public JsonActionResult<string> Reject([FromBody] T_PF_APPROVE entity)
        {
            return base.SafeExecute(() =>
            {
                var ret = string.Empty;
                var dbApprove = this.GetEntity<T_PF_APPROVE>(entity.ID.ToString(), false, "Nav_ApproveDetails");
                if (dbApprove == null)
                    this.ThrowError("020027");
                if (dbApprove.APPROVE_STATUS != (int)ApproveStatus.Doing)
                    this.ThrowError("020028");
                var node = dbApprove.Nav_ApproveDetails.FirstOrDefault(i => i.ID == entity.CurrentNode.ID);
                if (!node.IS_CURRENT)
                    this.ThrowError("020030");
                //查询消息表
                var task = this.GetEntity<T_FM_NOTIFICATION_TASK>(i => i.SOURCE_DATA_ID == entity.ID && i.USER_ID == node.APPROVE_USER_ID
                && i.NOTICE_STATUS == FMNoticeStatusEnum.未处理.GetInt(), false);
                if (task != null)
                {
                    task.NOTICE_STATUS = FMNoticeStatusEnum.正常已办.GetInt();
                    task.TASK_DT = DateTime.Now;
                    if (DateTime.Now > task.TASK_ENDDT)
                        task.NOTICE_STATUS = FMNoticeStatusEnum.超期办理.GetInt();
                }
                //修改节点状态
                node.NODE_APPROVE_TIME = DateTime.Now;
                node.NODE_APPROVE_STATUS = entity.CurrentNode.NODE_APPROVE_STATUS;
                node.IS_CURRENT = false;
                node.CONTEXT = entity.CurrentNode.CONTEXT;
                //驳回时状态改为驳回，并通知申请人重新提交
                dbApprove.APPROVE_STATUS = ApproveStatus.Reject.GetInt();
                var details = dbApprove.Nav_ApproveDetails;
                dbApprove.Nav_ApproveDetails = null;
                details.ForEach(i => i.Nav_Approve = null);
                var rejectInfo = this.GetEntity<T_PF_APPROVE_TEMP>(t => t.ID == dbApprove.APPROVE_TEMP_ID);
                if (rejectInfo != null && !string.IsNullOrEmpty(rejectInfo.REJECT_INTERFACE))
                    ret = rejectInfo.REJECT_INTERFACE;
                else
                    this.ThrowError("020030");
                UnifiedCommit(() =>
                {
                    if (task != null)
                        this.UpdateEntityNoCommit(task);
                    this.UpdateEntityNoCommit(dbApprove);
                    this.BantchUpdateEntityNoCommit(details);
                });
                return ret;
            });
        }

        /// <summary>
        /// 获取驳回意见
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost, Route("GetRejectContent")]
        public JsonActionResult<string> GetRejectContent(string id)
        {
            return base.SafeExecute(() =>
            {
                var result = string.Empty;
                var orgId = APT.Infrastructure.Api.AppContext.CurrentSession.OrgId;
                var newFilter = new BaseFilter(orgId);
                newFilter.SelectField = new List<string> { "Nav_ApproveDetails" };
                var approveInfo = this.GetEntities<T_PF_APPROVE>(t => t.DATA_ID == Guid.Parse(id), newFilter).OrderByDescending(m => m.CREATE_TIME).FirstOrDefault();
                if (approveInfo != null && approveInfo.Nav_ApproveDetails.Any())
                {
                    var detail = approveInfo.Nav_ApproveDetails.FirstOrDefault(t => t.NODE_APPROVE_STATUS == 20);
                    if (detail != null)
                    {
                        var userInfo = this.GetEntity<T_FM_USER>(t => t.ID == detail.APPROVE_USER_ID && t.ENABLE_STATUS == 0);
                        result = userInfo?.NAME + "驳回，内容：" + detail.CONTEXT;
                    }
                }
                return result;
            });
        }


        /// <summary>
        /// 获取驳回原因
        /// </summary>
        /// <param name="ApproveID"></param>
        /// <returns></returns>
        [HttpGet, Route("GetRejectContentByAPPID")]
        public JsonActionResult<string> GetRejectContentByAPPID(string ApproveID)
        {
            return SafeExecute<string>(() =>
            {
                if (string.IsNullOrEmpty(ApproveID))
                {
                    throw new Exception("传参有误");
                }
                var appID = Guid.Empty;
                try
                {
                    appID = new Guid(ApproveID);
                }
                catch
                {
                    throw new Exception("传参有误");
                }

                var approveDetail = GetEntity<T_PF_APPROVE_DETAIL>(e => e.APPROVE_ID == appID && !e.ISCANCEL && e.NODE_APPROVE_STATUS == 20);
                if (approveDetail != null)
                {
                    var userInfo = this.GetEntity<T_FM_USER>(t => t.ID == approveDetail.APPROVE_USER_ID);

                    if (DataHelper.GetRequestType(Request.Headers) == 2)
                    {
                        return approveDetail.CONTEXT + "\r\n" + (userInfo != null ? userInfo.NAME + "（" + approveDetail.MODIFY_TIME.Value.ToString("yyyy-MM-dd HH:mm") + "）" : approveDetail.MODIFY_TIME.Value.ToString("yyyy-MM-dd HH:mm"));
                    }
                    else
                    {
                        return userInfo?.NAME + " 驳回内容：" + approveDetail.CONTEXT;
                    }

                }
                else
                {
                    throw new Exception("未获取到驳回信息！");
                }
            });
        }

        /// <summary>
        /// 记录回调失败LOG
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost, Route("AddLog")]
        public JsonActionResult<bool> AddLog([FromBody] T_PF_APPROVE entity)
        {
            return base.SafeExecute(() =>
            {
                var loginUserId = APT.Infrastructure.Api.AppContext.CurrentSession.UserID;
                string data = "APPROVE:" + JsonConvert.SerializeObject(entity);
                SysLogService.AddLog(entity.ORG_ID.Value, loginUserId.Value, PFSysLogTypeEnum.FaildApproveCallBack, "PF119", "审批流回调失败-hmr记录", string.IsNullOrEmpty(entity.CALLBACK_INTERFACE) ? "" : "未执行回调：" + (entity.CALLBACK_INTERFACE + "ID=(" + entity.ID + ")&" + "DATA_ID=(" + entity.DATA_ID + ")"), data);
                return true;
            });
        }

        /// <summary>
        /// 根据数据id获取审核id
        /// </summary>
        /// <param name="keywordFilter">参数</param>
        /// <returns></returns>
        [HttpPost, Route("GetApproveInfo")]
        public JsonActionResult<List<T_PF_APPROVE>> GetApproveInfo([FromBody] KeywordFilter keywordFilter)
        {
            return SafeExecute<List<T_PF_APPROVE>>(() =>
            {
                Guid dataId = new Guid(keywordFilter.Keyword);
                bool isAPPROVEID = false;
                if (string.IsNullOrEmpty(keywordFilter.Keyword))
                    this.ThrowError("020005");
                if (!string.IsNullOrEmpty(keywordFilter.Parameter2))
                {

                    #region      反射demo 行255

                    var parms = keywordFilter.Parameter2.Split(',');
                    string tableName = parms[0];
                    string attribute = parms[1];
                    var dbType = APT.Infrastructure.Core.Refctor.ReflectHelper.FindTypeInCurrentDomain(tableName);
                    if (dbType != null)
                    {
                        //var mt = this.GetType().GetMethods().OrderBy(e => e.Name).ToList();
                        if (keywordFilter.Parameter2 == "T_BS_RISK_SUBMIT_NOTICE,RISK_SUBMIT_ID")
                        {
                            //标准化执行 > 安全检查管理 > 手动隐患上报
                            MethodInfo methodInfo = this.GetType().GetMethod("GetMyEntity2", BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static);
                            Expression<Func<T_BS_RISK_SUBMIT_NOTICE, bool>> expression2 = e => e.RISK_SUBMIT_ID == dataId;
                            var modelNo = methodInfo.MakeGenericMethod(new Type[] { dbType }).
                                    Invoke(this, new object[] { expression2 });

                            //T_BS_RISK_SUBMIT_NOTICE modelNo = GetEntity<T_BS_RISK_SUBMIT_NOTICE>(e => e.RISK_SUBMIT_ID == dataId);
                            if (modelNo != null)
                                dataId = new Guid(dbType.GetProperty("ID").GetValue(modelNo).ToString());
                            else
                                return null;
                            //throw new Exception("未获取到审批流信息！");
                        }
                        else if (keywordFilter.Parameter2 == "T_BS_SAFE_CHECK,APPROVE_CHECKAUDIT_ID")
                        {
                            MethodInfo methodInfo = this.GetType().GetMethod("GetMyEntity", BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static);
                            var entity = methodInfo.MakeGenericMethod(new Type[] { dbType }).
                                     Invoke(this, new object[] { dataId });

                            if (entity != null)
                            {
                                var prop = dbType.GetProperty(attribute).GetValue(entity);
                                if (prop != null)
                                {
                                    dataId = new Guid(prop.ToString());
                                    isAPPROVEID = true;
                                }
                                else
                                {
                                    dataId = Guid.Empty;
                                }
                            }

                        }
                        else if (keywordFilter.Parameter2 == "T_BS_SAFE_CHECK,APPROVE_ID")
                        {
                            MethodInfo methodInfo = this.GetType().GetMethod("GetMyEntity", BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static);
                            var entity = methodInfo.MakeGenericMethod(new Type[] { dbType }).
                                     Invoke(this, new object[] { dataId });

                            if (entity != null)
                            {
                                var prop = dbType.GetProperty(attribute).GetValue(entity);
                                if (prop != null)
                                {
                                    dataId = new Guid(prop.ToString());
                                    isAPPROVEID = true;
                                }
                                else
                                {
                                    dataId = Guid.Empty;
                                }
                            }

                        }
                    }

                    #endregion


                    ////以这种形式传参查看反射实现 一劳永逸
                    //if (keywordFilter.Parameter2 == "T_BS_RISK_SUBMIT_NOTICE,RISK_SUBMIT_ID")
                    //{
                    //    T_BS_RISK_SUBMIT_NOTICE modelNo = GetEntity<T_BS_RISK_SUBMIT_NOTICE>(e => e.RISK_SUBMIT_ID == dataId);
                    //    if (modelNo != null)
                    //        dataId = modelNo.ID;
                    //    else
                    //        return null;
                    //    //throw new Exception("未获取到审批流信息！");
                    //}
                    //else if (keywordFilter.Parameter2 == "T_BS_SAFE_CHECK,APPROVE_CHECKAUDIT_ID")
                    //{
                    //    var T_BS_SAFE_CHECK = GetEntity<T_BS_SAFE_CHECK>(e => e.ID == dataId);
                    //    if (T_BS_SAFE_CHECK != null && T_BS_SAFE_CHECK.APPROVE_CHECKAUDIT_ID.HasValue)
                    //    {
                    //        dataId = T_BS_SAFE_CHECK.APPROVE_CHECKAUDIT_ID.Value;
                    //        isAPPROVEID = true;
                    //    }
                    //    else
                    //    {
                    //        dataId = Guid.Empty;
                    //    }
                    //}


                }
                Expression<Func<T_PF_APPROVE, bool>> expression = e => e.DATA_ID == dataId;
                if (isAPPROVEID)
                {
                    expression = e => e.ID == dataId;
                }

                if (!string.IsNullOrEmpty(keywordFilter.Parameter1))
                {
                    expression = expression.And(e => e.PARAM == keywordFilter.Parameter1);
                }

                var orgId = APT.Infrastructure.Api.AppContext.CurrentSession.OrgId;
                var dbApprove = this.GetEntities<T_PF_APPROVE>(expression, new BaseFilter(keywordFilter.OrgId), new string[] { "Nav_ApproveDetails.Nav_ApproveUser.Nav_UserSignFiles.Nav_ImgFile.Nav_File" }).OrderByDescending(t => t.CREATE_TIME).ToList();
                if (!dbApprove.Any())
                    return null;
                return dbApprove;
            });
        }


        public bool MeetingMinutesBack(string id)
        {
            //状态修改
            Guid MeetingMinutesId = new Guid(id);
            T_SC_MT_MEETING_MINUTES entity = GetEntity<T_SC_MT_MEETING_MINUTES>(MeetingMinutesId);
            entity.STATUS = PFStandardStatus.Archived;//变成已归档
            this.UnifiedCommit(() =>
            {
                if (entity != null)
                    UpdateEntityNoCommit(entity);
            });
            return true;
        }
    }
}
