using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using WIDESEA_Core.DBManager;
using WIDESEA_Core.EFDbContext;
using WIDESEA_Core.Extensions;
using WIDESEA_Core.Infrastructure;
using WIDESEA_Core.ManageUser;
using WIDESEA_Core.Services;
using WIDESEA_Core.Utilities;
using WIDESEA_Entity.DomainModels;
using static Npgsql.PostgresTypes.PostgresCompositeType;

namespace WIDESEA_Core.WorkFlow
{
    public static class WorkFlowManager
    {
        public static bool Exists<T>()
        {
            return WorkFlowContainer.Exists<T>();
        }

        public static bool Exists<T>(T entity)
        {
            return WorkFlowContainer.Exists<T>() && GetAuditFlowTable<T>(typeof(T).GetKeyProperty().GetValue(entity).ToString()) != null;
        }
        public static bool Exists(string table)
        {
            return WorkFlowContainer.Exists(table);
        }
        /// <summary>
        /// 获取审批的数据
        /// </summary>
        public static async Task<object> GetAuditFormDataAsync(string tableKey, string table)
        {
            Type type = WorkFlowContainer.GetType(table);
            if (type == null)
            {
                return Array.Empty<object>();
            }
          
            var obj = typeof(WorkFlowManager).GetMethod("GetFormDataAsync").MakeGenericMethod(new Type[] { type })
                .Invoke(null, new object[] { tableKey, table }) as Task<object>;
            return await obj;
        }
        /// <summary>
        /// 审批表单数据查询与数据源转换
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tableKey"></param>
        /// <param name="table"></param>
        /// <returns></returns>
        public static async Task<object> GetFormDataAsync<T>(string tableKey, string table) where T : class
        {
            string[] fields = WorkFlowContainer.GetFormFields(table);
            if (fields == null || fields.Length == 0)
            {
                return Array.Empty<object>();
            }
            var tableOptions = await DBServerProvider.DbContext.Set<Sys_TableColumn>().Where(c => c.TableName == table && fields.Contains(c.ColumnName))
                   .Select(s => new { s.ColumnName, s.ColumnCnName, s.DropNo, isDate = s.IsImage == 4 }).ToListAsync();

            var condition = typeof(T).GetKeyName().CreateExpression<T>(tableKey, Enums.LinqExpressionType.Equal);
            //动态分库应该查询对应的数据库
            var data = await DBServerProvider.DbContext.Set<T>().Where(condition).FirstOrDefaultAsync();
            if (data==null)
            {
                Console.WriteLine($"未查到数据,表:{table},id:{tableKey}");
                return Array.Empty<object>();
            }

            List<Sys_Dictionary> dictionaries = new List<Sys_Dictionary>();
            var dicNos = tableOptions.Select(s => s.DropNo).ToList();
            if (dicNos.Count > 0)
            {
                dictionaries = DictionaryManager.GetDictionaries(dicNos, true).ToList();
            }

            List<object> list = new List<object>();
            var properties = typeof(T).GetProperties();

            foreach (var field in fields)
            {
                var property = properties.Where(c => c.Name == field).FirstOrDefault();
                string value = property.GetValue(data)?.ToString();

                var option = tableOptions.Where(c => c.ColumnName == field).FirstOrDefault();
                string name = option?.ColumnCnName;
                if (string.IsNullOrEmpty(name))
                {
                    name = property.GetDisplayName();
                }
                if (option == null || string.IsNullOrEmpty(value))
                {
                    list.Add(new
                    {
                        name,
                        value = value ?? ""
                    });
                    continue;
                }
                if (option.isDate)
                {
                    value = value.GetDateTime().Value.ToString("yyyy-MM-dd");
                }
                else if (!string.IsNullOrEmpty(option.DropNo))
                {
                    string val = dictionaries.Where(c => c.DicNo == option.DropNo).FirstOrDefault()
                         ?.Sys_DictionaryList
                         //这里多选的暂时没处理
                         ?.Where(c => c.DicValue == value)?.Select(s => s.DicName)
                         .FirstOrDefault();
                    if (!string.IsNullOrEmpty(val))
                    {
                        value = val;
                    }
                }
                list.Add(new
                {
                    name,
                    value
                });
            }
            return list;
        }

        public static int GetAuditStatus<T>(string value)
        {
            return GetAuditFlowTable<T>(value)?.AuditStatus ?? 0;
        }

        public static Sys_WorkFlowTable GetAuditFlowTable<T>(string workTableKey)
        {
            var table = DBServerProvider.DbContext.Set<Sys_WorkFlowTable>()
                   .Where(x => x.WorkTable == typeof(T).GetEntityTableName() && x.WorkTableKey == workTableKey)
                   // .Select(s => new { s.CurrentStepId,s.AuditStatus})
                   .FirstOrDefault();
            return table;
        }

        private static void Rewrite<T>(T entity, Sys_WorkFlow workFlow, bool changeTableStatus) where T : class
        {
            var autditProperty = typeof(T).GetProperties().Where(x => x.Name.ToLower() == "auditstatus").FirstOrDefault();
            if (autditProperty == null)
            {
                return;
            }

            string value = typeof(T).GetKeyProperty().GetValue(entity).ToString();

            var dbContext = DBServerProvider.DbContext;


            var workTable = dbContext.Set<Sys_WorkFlowTable>().Where(x => x.WorkTableKey == value && x.WorkFlow_Id == workFlow.WorkFlow_Id)
                   .AsNoTracking()
                  .Include(x => x.Sys_WorkFlowTableStep).FirstOrDefault();
            if (workTable == null || workFlow.Sys_WorkFlowStep == null || workFlow.Sys_WorkFlowStep.Count == 0)
            {
                Console.WriteLine($"未查到流程数据,id:{workFlow.WorkFlow_Id}");
                return;
            }
            //  workTable.CurrentOrderId = 1;

            //这里还未处理回退到上一个节点

            //重新设置第一个节点(有可能是返回上一个节点)
            string startStepId = workTable.Sys_WorkFlowTableStep.Where(x => x.StepAttrType == StepType.start.ToString())
                 .Select(s => s.StepId).FirstOrDefault();

            workTable.CurrentStepId = workTable.Sys_WorkFlowTableStep.Where(x => x.ParentId == startStepId).Select(s => s.StepId).FirstOrDefault();

            workTable.AuditStatus = (int)AuditStatus.待审核;
            workTable.Sys_WorkFlowTableStep.ForEach(item =>
            {
                item.Enable = 0;
                item.AuditId = null;
                item.Auditor = null;
                item.AuditDate = null;
                item.Remark = null;
            });

            if (changeTableStatus)
            {
                dbContext.Entry(entity).State = EntityState.Detached;
                autditProperty.SetValue(entity, 0);
                dbContext.Entry(entity).Property(autditProperty.Name).IsModified = true;
            }

            dbContext.Entry(workTable).State = EntityState.Detached;
            dbContext.Update(workTable);
            dbContext.SaveChanges();

        }
        /// <summary>
        /// 新建时写入流程
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="rewrite">是否重新生成流程</param>
        /// <param name="changeTableStatus">是否修改原表的审批状态</param>
        public static void AddProcese<T>(T entity, bool rewrite = false, bool changeTableStatus = true, Action<T, List<int>> addWorkFlowExecuted = null) where T : class
        {
            WorkFlowTableOptions workFlow = WorkFlowContainer.GetFlowOptions(entity);
            //没有对应的流程信息
            if (workFlow == null || workFlow.FilterList.Count == 0)
            {
                return;
            }
            workFlow.WorkTableName = WorkFlowContainer.GetName<T>();
            string workTable = typeof(T).GetEntityTableName();

            ////重新生成流程
            if (rewrite)
            {
                Rewrite(entity, workFlow, changeTableStatus);
                return;
            }

            var userInfo = UserContext.Current.UserInfo;
            Guid workFlowTable_Id = Guid.NewGuid();
            Sys_WorkFlowTable workFlowTable = new Sys_WorkFlowTable()
            {
                WorkFlowTable_Id = workFlowTable_Id,
                AuditStatus = (int)AuditStatus.待审核,
                Enable = 1,
                WorkFlow_Id = workFlow.WorkFlow_Id,
                WorkName = workFlow.WorkName,
                WorkTable = workTable,
                WorkTableKey = typeof(T).GetKeyProperty().GetValue(entity).ToString(),
                WorkTableName = workFlow.WorkTableName,
                CreateID = userInfo.User_Id,
                CreateDate = DateTime.Now,
                Creator = userInfo.UserTrueName
            };
            //生成流程的下一步
            var steps = workFlow.FilterList.Where(x => x.StepAttrType == StepType.start.ToString()).Select(s => new Sys_WorkFlowTableStep()
            {
                Sys_WorkFlowTableStep_Id = Guid.NewGuid(),
                WorkFlowTable_Id = workFlowTable_Id,
                WorkFlow_Id = workFlow.WorkFlow_Id,
                StepId = s.StepId,
                StepName = s.StepName ?? "流程开始",
                StepAttrType = s.StepAttrType,
                NextStepId = null,
                ParentId = null,
                StepType = s.StepType,
                StepValue = s.StepValue,
                OrderId = 0,
                Enable = 1,
                CreateDate = DateTime.Now,
                Creator = userInfo.UserTrueName,
                CreateID = userInfo.User_Id
            }).ToList();

            var entities = new List<T>() { entity };
            for (int i = 0; i < steps.Count; i++)
            {
                var item = steps[i];
                //查找下一个满足条件的节点数据
                FilterOptions filter = workFlow.FilterList.Where(c => c.ParentIds.Contains(item.StepId)
                                                                && c.Expression != null
                                                                && entities.Any(((Func<T, bool>)c.Expression))
                                                                ).FirstOrDefault();
                //未找到满足条件的找无条件的节点
                if (filter == null)
                {
                    filter = workFlow.FilterList.Where(c => c.ParentIds.Contains(item.StepId) && c.Expression == null).FirstOrDefault();
                }
                if (filter != null)
                {
                    var setp = workFlow.Sys_WorkFlowStep.Where(x => x.StepId == filter.StepId).Select(s => new Sys_WorkFlowTableStep()
                    {
                        Sys_WorkFlowTableStep_Id = Guid.NewGuid(),
                        WorkFlowTable_Id = workFlowTable_Id,
                        WorkFlow_Id = s.WorkFlow_Id,

                        StepId = s.StepId,
                        StepName = s.StepName,
                        StepAttrType = s.StepAttrType,
                        NextStepId = null,
                        ParentId = item.StepId,
                        StepType = s.StepType,
                        StepValue = s.StepValue,
                        OrderId = i + 1,
                        Enable = 1,
                        CreateDate = DateTime.Now,
                    }).FirstOrDefault();

                    //显示后续部门与角色审批人待完

                    //设置下个审核节点
                    item.NextStepId = setp.StepId;
                    if (!steps.Any(x => x.StepId == setp.StepId))
                    {
                        steps.Add(setp);
                    }
                }
                else
                {
                    //找不到满足条件的节点,直接结束流程
                    var end = workFlow.Sys_WorkFlowStep.Where(c => c.StepAttrType == StepType.end.ToString()).ToList();

                    if (end.Count > 0)
                    {
                        item.NextStepId = end[0].StepId;
                        steps.Add(end.Select(s => new Sys_WorkFlowTableStep()
                        {
                            Sys_WorkFlowTableStep_Id = Guid.NewGuid(),
                            WorkFlowTable_Id = workFlowTable_Id,
                            WorkFlow_Id = s.WorkFlow_Id,
                            StepId = s.StepId,
                            StepName = s.StepName,
                            StepAttrType = s.StepAttrType,
                            NextStepId = null,
                            ParentId = item.StepId,
                            StepType = s.StepType,
                            StepValue = s.StepValue,
                            OrderId = i + 1,
                            Enable = 1,
                            CreateDate = DateTime.Now,
                        }).FirstOrDefault());
                        i = steps.Count + 1;
                    }
                }
            }

            foreach (var setp in steps)
            {
                if (setp.StepType == (int)AuditType.用户审批)
                {
                    setp.AuditId = setp.StepValue.GetInt();
                }
            }

            //没有满足流程的数据不走流程
            int count = steps.Where(x => x.StepAttrType != StepType.start.ToString() && x.StepAttrType != StepType.end.ToString()).Count();
            if (count == 0)
            {
                return;
            }

            //设置进入流程后的第一个审核节点,(开始节点的下一个节点)
            var nodeInfo = steps.Where(x => x.ParentId == steps[0].StepId).Select(s => new { s.StepId, s.StepName }).FirstOrDefault();
            workFlowTable.CurrentStepId = nodeInfo.StepId;
            workFlowTable.StepName = nodeInfo.StepName;

            workFlowTable.Sys_WorkFlowTableStep = steps;

            //写入日志
            var log = new Sys_WorkFlowTableAuditLog()
            {
                Id = Guid.NewGuid(),
                WorkFlowTable_Id = workFlowTable.WorkFlowTable_Id,
                CreateDate = DateTime.Now,
                AuditStatus = (int)AuditStatus.待审核,
                Remark = $"[{userInfo.UserTrueName}]提交了数据"
            };
            var dbContext = DBServerProvider.DbContext;
            dbContext.Set<Sys_WorkFlowTable>().Add(workFlowTable);
            dbContext.Set<Sys_WorkFlowTableAuditLog>().Add(log);
            dbContext.SaveChanges();
        }


        /// <summary>
        /// 审核
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="status"></param>
        /// <param name="remark"></param>
        /// <param name="autditProperty"></param>
        /// <param name="workFlowExecuting"></param>
        /// <param name="workFlowExecuted"></param>
        /// <returns></returns>
        public static WebResponseContent Audit<T>(T entity, AuditStatus status, string remark,
            PropertyInfo autditProperty,
             Func<T, AuditStatus, bool, WebResponseContent> workFlowExecuting,
             Func<T, AuditStatus, List<int>, bool, WebResponseContent> workFlowExecuted,
             bool init = false,
             Action<T, List<int>> initInvoke = null
            ) where T : class
        {
            WebResponseContent webResponse = new WebResponseContent(true);
            if (init)
            {
                if (!WorkFlowContainer.Exists<T>())
                {
                    return webResponse;
                }
            }
            var dbContext = DBServerProvider.DbContext;
            dbContext.QueryTracking = true; ;
            var query = dbContext.Set<T>();

            var keyProperty = typeof(T).GetKeyProperty();
            string key = keyProperty.GetValue(entity).ToString();
            string workTable = typeof(T).GetEntityTableName();

            Sys_WorkFlowTable workFlow = dbContext.Set<Sys_WorkFlowTable>()
                       .Where(x => x.WorkTable == workTable && x.WorkTableKey == key)
                        .Include(x => x.Sys_WorkFlowTableStep)
                       .FirstOrDefault();

            if (workFlow == null)
            {
                return webResponse.Error("未查到流程信息,请检查数据是否被删除");
            }


            workFlow.AuditStatus = (int)status;

            var currentStep = workFlow.Sys_WorkFlowTableStep.Where(x => x.StepId == workFlow.CurrentStepId).FirstOrDefault();

            if (currentStep == null)
            {
                return webResponse.Error($"未查到流程陈点[workFlow.CurrentStepId]信息,请检查数据是否被删除");
            }
            Sys_WorkFlowTableStep nextStep = null;
            //获取下一步审核id
            var nextStepId = currentStep.NextStepId;

            nextStep = workFlow.Sys_WorkFlowTableStep.Where(x => x.StepId == nextStepId).FirstOrDefault();

            var user = UserContext.Current.UserInfo;
            //生成审核记录
            var log = new Sys_WorkFlowTableAuditLog()
            {
                Id = Guid.NewGuid(),
                StepId = currentStep.StepId,
                WorkFlowTable_Id = currentStep.WorkFlowTable_Id,
                WorkFlowTableStep_Id = currentStep.Sys_WorkFlowTableStep_Id,
                AuditDate = DateTime.Now,
                AuditId = user.User_Id,
                Auditor = user.UserTrueName,
                AuditResult = remark,
                Remark = remark,
                AuditStatus = (int)status,
                CreateDate = DateTime.Now,
                StepName = currentStep.StepName
            };
            var filterOptions = WorkFlowContainer.GetFlowOptions(x => x.WorkTable == workTable)
                 .FirstOrDefault()
                 ?.FilterList
                 ?.Where(x => x.StepId == currentStep.StepId)
                 ?.FirstOrDefault();
            if (filterOptions != null)
            {
                //审核未通过或者驳回
                if (!CheckAuditStatus(workFlow, filterOptions, currentStep, status))
                {
                    //记录日志
                    dbContext.Set<Sys_WorkFlowTableAuditLog>().Add(log);

                    string msg = null;
                    if (AuditStatus.审核未通过 == status)
                    {
                        if (filterOptions.AuditRefuse == (int)AuditRefuse.返回上一节点)
                        {
                            msg = "审批未通过,返回上一节点";
                        }
                        else if (filterOptions.AuditRefuse == (int)AuditRefuse.流程重新开始)
                        {
                            msg = "审批未通过,流程重新开始";
                        }
                    }
                    else if (AuditStatus.驳回 == status)
                    {
                        if (filterOptions.AuditBack == (int)AuditBack.返回上一节点)
                        {
                            msg = "审批被驳回,返回上一节点";
                        }
                        else if (filterOptions.AuditBack == (int)AuditBack.流程重新开始)
                        {
                            msg = "审批被驳回,流程重新开始";
                        }
                    }
                    var auditLog = new Sys_WorkFlowTableAuditLog()
                    {
                        Id = Guid.NewGuid(),
                        StepId = currentStep.StepId,
                        WorkFlowTable_Id = currentStep.WorkFlowTable_Id,
                        WorkFlowTableStep_Id = currentStep.Sys_WorkFlowTableStep_Id,
                        AuditDate = DateTime.Now,
                        AuditId = user.User_Id,
                        Auditor = user.UserTrueName,
                        AuditResult = remark,
                        Remark = msg,
                        AuditStatus = (int)status,
                        CreateDate = DateTime.Now,
                        StepName = currentStep.StepName
                    };
                    dbContext.Set<Sys_WorkFlowTableAuditLog>().Add(auditLog);
                    //autditProperty.SetValue(entity, (int)status);
                    //query.Update(entity);
                    //修改状态
                    dbContext.Set<Sys_WorkFlowTable>().Update(workFlow);
                    dbContext.SaveChanges();
                    dbContext.Entry(workFlow).State = EntityState.Detached;

                    //发送邮件(appsettings.json配置文件里添加邮件信息)
                    SendMail(workFlow, filterOptions, nextStep, dbContext);

                    if (workFlowExecuted != null)
                    {
                        webResponse = workFlowExecuted.Invoke(entity, status, GetAuditUserIds(nextStep?.StepType ?? 0, nextStep?.StepValue), false);
                    }
                    return webResponse;
                }
            }


            if (autditProperty == null)
            {
                autditProperty = typeof(T).GetProperties().Where(s => s.Name.ToLower() == "auditstatus").FirstOrDefault();
            }
            bool isLast = false;


            //更新明细记录
            workFlow.Sys_WorkFlowTableStep.ForEach(x =>
            {
                if (workFlow.CurrentStepId == x.StepId)
                {
                    x.AuditId = user.User_Id;
                    x.Auditor = user.UserTrueName;
                    x.AuditDate = DateTime.Now;
                    //如果审核拒绝或驳回并退回上一步,待完
                    x.AuditStatus = (int)status;
                    x.Remark = remark;
                }
            });

            //没有找到下一步审批,审核完成
            if ((nextStep == null || nextStep.StepAttrType == StepType.end.ToString()))
            {
                if (status == AuditStatus.审核通过)
                {
                    workFlow.CurrentStepId = "审核完成";
                }
                else
                {
                    workFlow.CurrentStepId = "流程结束";
                }
                workFlow.AuditStatus = (int)status;

                //发送邮件(appsettings.json配置文件里添加邮件信息)
                SendMail(workFlow, filterOptions, nextStep, dbContext);

                autditProperty.SetValue(entity, (int)status);
                dbContext.Set<Sys_WorkFlowTable>().Update(workFlow);
                query.Update(entity);
                dbContext.Set<Sys_WorkFlowTableAuditLog>().Add(log);
                dbContext.SaveChanges();

                if (workFlowExecuted != null)
                {
                    webResponse = workFlowExecuted.Invoke(entity, status, GetAuditUserIds(nextStep?.StepType ?? 0, nextStep?.StepValue), isLast);
                }

                return webResponse;
            }

            //指向下一个人审批
            if (nextStep != null && status == AuditStatus.审核通过)
            {
                workFlow.CurrentStepId = nextStep.StepId;
                //原表显示审核中状态
                autditProperty.SetValue(entity, (int)AuditStatus.审核中);
                workFlow.AuditStatus = (int)AuditStatus.审核中;
            }
            else
            {
                autditProperty.SetValue(entity, (int)status);
            }


            //下一个节点=null或节下一个节点为结束节点,流程结束
            if (nextStep == null || workFlow.Sys_WorkFlowTableStep.Exists(c => c.StepId == nextStep.StepId && c.StepAttrType == StepType.end.ToString()))
            {
                isLast = true;
            }

            if (workFlowExecuting != null)
            {
                webResponse = workFlowExecuting.Invoke(entity, status, isLast);
                if (!webResponse.Status)
                {
                    return webResponse;
                }
            }

            query.Update(entity);
            dbContext.Set<Sys_WorkFlowTable>().Update(workFlow);
            dbContext.Set<Sys_WorkFlowTableAuditLog>().Add(log);

            dbContext.SaveChanges();
            dbContext.Entry(workFlow).State = EntityState.Detached;
            if (workFlowExecuted != null)
            {
                webResponse = workFlowExecuted.Invoke(entity, status, GetAuditUserIds(nextStep?.StepType ?? 0, nextStep?.StepValue), isLast);
            }
            return webResponse;

        }

        private static bool CheckAuditStatus(Sys_WorkFlowTable workFlow, FilterOptions filterOptions, Sys_WorkFlowTableStep currentStep, AuditStatus status)
        {
            //如果审核拒绝或驳回并退回上一步,待完
            //重新配置流程待完
            if (status != AuditStatus.审核未通过 && status != AuditStatus.驳回)
            {
                return true;
            }
            if (filterOptions.AuditRefuse == (int)AuditRefuse.返回上一节点 || filterOptions.AuditBack == (int)AuditBack.返回上一节点)
            {
                var preStep = workFlow.Sys_WorkFlowTableStep.Where(x => x.NextStepId == currentStep.StepId && x.StepAttrType == StepType.node.ToString()).FirstOrDefault();
                if (preStep != null)
                {
                    preStep.AuditStatus = null;
                    preStep.AuditId = null;
                    preStep.AuditDate = null;
                    preStep.Auditor = null;

                    workFlow.CurrentStepId = preStep.StepId;
                    workFlow.AuditStatus = (int)AuditStatus.审核中;

                    DBServerProvider.DbContext.Update(preStep);
                }

                return false;
            }
            else if (filterOptions.AuditRefuse == (int)AuditRefuse.流程重新开始 || filterOptions.AuditBack == (int)AuditBack.流程重新开始)
            {
                //重新开始
                var steps = workFlow.Sys_WorkFlowTableStep.Where(x => x.StepAttrType == StepType.node.ToString() && (x.AuditStatus >= 0)).ToList();
                if (steps.Count > 0)
                {
                    foreach (var item in steps)
                    {
                        item.AuditStatus = null;
                        item.AuditId = null;
                        item.AuditDate = null;
                        item.Auditor = null;
                    }
                    //重新指向第一个节点
                    workFlow.CurrentStepId = steps.OrderBy(c => c.OrderId).Select(c => c.StepId).FirstOrDefault();
                    workFlow.AuditStatus = (int)AuditStatus.审核中;

                    DBServerProvider.DbContext.UpdateRange(steps);
                }
                return false;
            }
            return true;
        }

        private static void SendMail(Sys_WorkFlowTable workFlow, FilterOptions filterOptions, Sys_WorkFlowTableStep nextStep, VOLContext dbContext)
        {
            if (filterOptions.SendMail != 1)
            {
                return;
            }
            if (nextStep == null)
            {
                nextStep = new Sys_WorkFlowTableStep() { };
            }
            //审核发送邮件通知待完
            var userIds = GetAuditUserIds(nextStep.StepType ?? 0, nextStep.StepValue);
            if (userIds.Count == 0)
            {
                return;
            }
            var emails = dbContext.Set<Sys_User>()
                 .Where(x => userIds.Contains(x.User_Id) && x.Email != null & x.Email != "").Select(s => s.Email)
                .ToList();
            Task.Run(() =>
            {
                string msg = "";
                try
                {
                    string title = $"有新的任务待审批:流程【{workFlow.WorkName}】,任务【{nextStep.StepName}】";
                    MailHelper.Send(title, title, string.Join(";", emails));
                    msg = $"审批流程发送邮件,流程名称:{workFlow.WorkName},流程id:{workFlow.WorkFlow_Id},步骤:{nextStep.StepName},步骤Id:{nextStep.StepId},收件人:{string.Join(";", emails)}";
                    Logger.AddAsync(msg);
                }
                catch (Exception ex)
                {
                    msg += "邮件发送异常:";
                    Logger.AddAsync(msg, ex.Message + ex.StackTrace);
                }
            });
        }

        /// <summary>
        /// 获取审批人的id
        /// </summary>
        /// <param name="stepType"></param>
        /// <returns></returns>
        private static List<int> GetAuditUserIds(int stepType, string nextId = null)
        {
            List<int> userIds = new List<int>();
            if (stepType == 0 || string.IsNullOrEmpty(nextId))
            {
                return userIds;
            }
            if (stepType == (int)AuditType.角色审批)
            {
                int roleId = nextId.GetInt();
                userIds = DBServerProvider.DbContext.Set<Sys_User>().Where(s => s.Role_Id == roleId).Take(50).Select(s => s.User_Id).ToList();
            }
            else if (stepType == (int)AuditType.部门审批)
            {
                Guid departmentId = nextId.GetGuid() ?? Guid.Empty;
                userIds = DBServerProvider.DbContext.Set<Sys_UserDepartment>().Where(s => s.DepartmentId == departmentId && s.Enable == 1).Take(50).Select(s => s.UserId).ToList();
            }
            else
            {
                return nextId.Split(",").Select(c => c.GetInt()).ToList();
            }
            return userIds;
        }
    }
}