using AutoMapper;
using Newtonsoft.Json;
using OASystem.Domain;
using OASystem.Domain.Dtos.Groups;
using OASystem.Domain.Entities.Groups;
using System.Reflection;
namespace OASystem.Infrastructure.Repositories.Groups
{
    /// 
    /// 团组流程总览表仓储
    /// 
    public class ProcessOverviewRepository : BaseRepository
    {
        private readonly IMapper _mapper;
        private readonly DelegationInfoRepository _groupRep;
        public ProcessOverviewRepository(SqlSugarClient sqlSugar, IMapper mapper, DelegationInfoRepository groupRep) : base(sqlSugar)
        {
            _mapper = mapper;
            _groupRep = groupRep;
        }
        /// 
        /// 团组流程初始化
        /// 
        /// 创建流程请求参数
        /// 创建的流程信息
        public async Task ProcessInitAsync(int groupId, int currUserId)
        {
            //团组验证
            var groupInfo = await _sqlSugar.Queryable().FirstAsync(g => g.Id == groupId);
            if (groupInfo == null)
            {
                return new Result { Code = 400, Msg = "团组不存在" };
            }
            // 检查是否已存在流程
            var existingProcesses = await _sqlSugar.Queryable().Where(p => p.GroupId == groupId).ToListAsync();
            if (existingProcesses.Any())
            {
                return new Result { Code = 400, Msg = "该团组的流程已存在" };
            }
            //处理签证国家
            var visaCountries = _groupRep.GroupSplitCountry(groupInfo.VisitCountry);
            // 定义默认的流程节点
            var processs = Grp_ProcessOverview.ProcessInit(groupId, currUserId, visaCountries);
            _sqlSugar.BeginTran();
            foreach (var item in processs)
            {
                var processId = await _sqlSugar.Insertable(item).ExecuteReturnIdentityAsync();
                if (processId < 1)
                {
                    _sqlSugar.RollbackTran();
                    return new Result { Code = 400, Msg = "团组流程进度总览表添加失败!" };
                }
                // 记录流程日志
                await LogProcessOpAsync(null, item, "Create", currUserId);
                var nodes = item.Nodes.Select((nodeDto, index) => new Grp_ProcessNode
                {
                    ProcessId = processId,
                    NodeName = nodeDto.NodeName,
                    NodeOrder = nodeDto.NodeOrder,
                    OverallStatus = nodeDto.OverallStatus,
                    //Country = nodeDto.Country,
                    IsCurrent = nodeDto.IsCurrent,
                    Remark = nodeDto.Remark
                }).ToList();
                var nodeIds = await _sqlSugar.Insertable(nodes).ExecuteCommandAsync();
                if (nodeIds < 1)
                {
                    _sqlSugar.RollbackTran();
                    return new Result { Code = 400, Msg = "团组流程进度流程节点添加失败!" };
                }
                //记录节点日志
                foreach (var node in nodes)
                {
                    await LogNodeOpAsync(null, node, "Create", currUserId);
                }
                
            }
            _sqlSugar.CommitTran();
            return new Result { Code = 200, Msg = "添加成功!" }; ;
        }
        /// 
        /// 获取团组的所有流程及流程详情
        /// 
        /// 创建流程请求参数
        /// 创建的流程信息
        public async Task ProcessesDetailsAsync(int groupId)
        {
            //团组验证
            var groupInfo = await _sqlSugar.Queryable().FirstAsync(g => g.Id == groupId);
            if (groupInfo == null)
            {
                return new Result { Code = 400, Msg = "团组不存在" };
            }
            // 检查是否已存在流程
            var existingProcesses = await _sqlSugar.Queryable().Where(p => p.GroupId == groupId).ToListAsync();
            if (!existingProcesses.Any())
            {
                //新建团组流程
                var res = await ProcessInitAsync(groupId, 4);
                if (res.Code != 200)
                {
                    return res;
                }
            }
            var users = await _sqlSugar.Queryable().ToListAsync();
            var processData = await _sqlSugar.Queryable()
                .Where(p => p.GroupId == groupId && p.IsDel == 0)
                .Mapper(p => p.Nodes, p => p.Nodes.First().ProcessId)
                .ToListAsync();
            var processes = processData.Select(p => new
            {
                p.Id,
                p.GroupId,
                p.ProcessType,
                ProcessName = p.ProcessType.GetEnumDescription(),
                //p.OverallStatus,
                //StatusText = p.OverallStatus.GetDescription(),
                Nodes = p.Nodes.Select(n =>
                {
                    //单独处理签证板块
                    var visaSubNodes = new List();
                    string remark = string.Empty;
                    if (p.ProcessType == GroupProcessType.Visa)
                    {
                        visaSubNodes = JsonConvert.DeserializeObject>(n.Remark);
                    }
                    return new
                    {
                        n.Id,
                        n.ProcessId,
                        n.NodeOrder,
                        n.NodeName,
                        n.OverallStatus,
                        StatusText = n.OverallStatus.GetEnumDescription(),
                        Operator = users.FirstOrDefault(u => u.Id == n.Operator)?.CnName ?? "-",
                        OpeateTime = n.OperationTime.HasValue ? n.OperationTime.Value.ToString("yyyy-MM-dd HH:mm:ss") : "-",
                        //节点类型为签证时使用
                        visaSubNodes
                    };
                }).OrderBy(n => n.NodeOrder).ToList()
            }).ToList();
            return new Result { Code = 200, Data = processes, Msg = "查询成功!" };
        }
        /// 
        /// 更新节点状态
        /// 
        /// 节点ID
        /// 当前用户ID
        /// 流程状态,默认为已完成
        /// 操作结果
        public async Task UpdateNodeStatusAsync(int nodeId, int currUserId, ProcessStatus processStatus = ProcessStatus.Completed)
        {
            try
            {
                // 使用事务确保数据一致性
                var result = await _sqlSugar.Ado.UseTranAsync(async () =>
                {
                    // 1. 获取并验证节点
                    var node = await _sqlSugar.Queryable()
                        .FirstAsync(n => n.Id == nodeId && n.IsDel == 0);
                    if (node == null)
                    {
                        throw new BusinessException("当前节点不存在或已被删除。");
                    }
                    // 新增验证:当前节点已完成,不可操作
                    ValidateNodeOperation(node, processStatus);
                    //存储更新前的值
                    var before = new Grp_ProcessNode() { 
                        Id = node.Id,
                        ProcessId = node.ProcessId,
                        NodeName = node.NodeName,
                        NodeOrder = node.NodeOrder,
                        OverallStatus = node.OverallStatus,
                        Operator = node.Operator,
                        OperationTime = node.OperationTime,
                        IsCurrent = node.IsCurrent,
                    };
                    // 2. 更新节点状态
                    node.OverallStatus = processStatus;
                    node.Operator = currUserId;
                    node.OperationTime = DateTime.Now;
                    var updateCount = await _sqlSugar.Updateable(node)
                        .UpdateColumns(n => new
                        {
                            n.OverallStatus,
                            n.Operator,
                            n.OperationTime
                        })
                        .ExecuteCommandAsync();
                    if (updateCount == 0)
                    {
                        throw new BusinessException("节点状态更新失败。");
                    }
                    //记录节点日志
                    await LogNodeOpAsync(before, node, "Update", currUserId);
                    // 3. 如果是完成当前节点,处理流程流转
                    if (processStatus == ProcessStatus.Completed && node.IsCurrent)
                    {
                        await ProcessCurrentNodeCompletionAsync(node, currUserId);
                    }
                    return new Result { Code = StatusCodes.Status200OK, Msg = "操作成功。" };
                });
                return result.IsSuccess ? result.Data : new Result
                {
                    Code = StatusCodes.Status500InternalServerError,
                    Msg = result.ErrorMessage
                };
            }
            catch (BusinessException ex)
            {
                // 业务异常
                return new Result { Code = StatusCodes.Status400BadRequest, Msg = ex.Message };
            }
            catch (Exception ex)
            {
                // 系统异常
                return new Result { Code = StatusCodes.Status500InternalServerError, Msg = "系统错误,请稍后重试" };
            }
        }
        /// 
        /// 验证节点操作权限
        /// 
        /// 流程节点
        /// 目标状态
        private static void ValidateNodeOperation(Grp_ProcessNode node, ProcessStatus targetStatus)
        {
            // 验证节点是否已完成
            if (node.OverallStatus == ProcessStatus.Completed)
            {
                throw new BusinessException("当前节点已完成,不可重复操作。");
            }
            // 验证状态流转是否合法(可选)
            if (targetStatus != ProcessStatus.Completed)
            {
                throw new BusinessException("未开始或者进行中的节点只能重新完成,不可进行其他操作。");
            }
            // 验证是否尝试将已完成节点改为其他状态
            if (node.OverallStatus == ProcessStatus.Completed && targetStatus != ProcessStatus.Completed)
            {
                throw new BusinessException("已完成节点不可修改状态。");
            }
        }
        /// 
        /// 处理当前节点完成后的流程流转
        /// 
        private async Task ProcessCurrentNodeCompletionAsync(Grp_ProcessNode currentNode, int currUserId)
        {
            // 1. 获取流程信息
            var process = await _sqlSugar.Queryable()
                .FirstAsync(p => p.Id == currentNode.ProcessId && p.IsDel == 0);
            if (process == null)
            {
                throw new BusinessException("关联的流程不存在。");
            }
            var processBefore = new Grp_ProcessOverview()
            {
                Id = process.Id,
                GroupId = process.GroupId,
                ProcessOrder = process.ProcessOrder,
                ProcessType = process.ProcessType,
                OverallStatus = process.OverallStatus,
                StartTime = process.StartTime,
                EndTime = process.EndTime,
                UpdatedUserId = process.UpdatedUserId,
                UpdatedTime = process.UpdatedTime
            };
            // 2. 取消当前节点的当前状态
            var before = new Grp_ProcessNode()
            {
                Id = currentNode.Id,
                ProcessId = currentNode.ProcessId,
                NodeName = currentNode.NodeName,
                NodeOrder = currentNode.NodeOrder,
                OverallStatus = currentNode.OverallStatus,
                Operator = currentNode.Operator,
                OperationTime = currentNode.OperationTime,
                IsCurrent = currentNode.IsCurrent,
            };
            currentNode.IsCurrent = false;
            await _sqlSugar.Updateable(currentNode)
                .UpdateColumns(n => new { n.IsCurrent })
                .ExecuteCommandAsync();
            // 2.1 记录节点日志 取消当前节点状态
            await LogNodeOpAsync(before, currentNode, "Update", currUserId);
            // 3. 查找并激活下一个节点
            var nextNode = await _sqlSugar.Queryable()
                .Where(n => n.ProcessId == currentNode.ProcessId
                         && n.NodeOrder == currentNode.NodeOrder + 1
                         && n.IsDel == 0)
                .FirstAsync();
            if (nextNode != null)
            {
                var nextNodeBefore = new Grp_ProcessNode()
                {
                    Id = nextNode.Id,
                    ProcessId = nextNode.ProcessId,
                    NodeName = nextNode.NodeName,
                    NodeOrder = nextNode.NodeOrder,
                    OverallStatus = nextNode.OverallStatus,
                    Operator = nextNode.Operator,
                    OperationTime = nextNode.OperationTime,
                    IsCurrent = nextNode.IsCurrent,
                };
                // 激活下一个节点
                nextNode.IsCurrent = true;
                nextNode.OverallStatus = ProcessStatus.InProgress;
                //nextNode.Operator = currUserId;
                //nextNode.OperationTime = DateTime.Now;
                var updateCount = await _sqlSugar.Updateable(nextNode)
                    .UpdateColumns(n => new
                    {
                        n.IsCurrent,
                        n.OverallStatus,
                        n.Operator,
                        n.OperationTime
                    })
                    .ExecuteCommandAsync();
                if (updateCount == 0)
                {
                    throw new BusinessException("激活下一节点失败");
                }
                // 1.1 记录节点日志 激活下一节点当前节点状态
                await LogNodeOpAsync(nextNodeBefore, nextNode, "Start", currUserId);
                // 更新流程状态为进行中
                process.OverallStatus = ProcessStatus.InProgress;
            }
            else
            {
                // 下一节点不存在,整个流程完成
                process.OverallStatus = ProcessStatus.Completed;
                process.EndTime = DateTime.Now;
            }
            // 4. 更新流程信息
            process.UpdatedUserId = currUserId;
            process.UpdatedTime = DateTime.Now;
            var processUpdateCount = await _sqlSugar.Updateable(process)
                .UpdateColumns(p => new
                {
                    p.OverallStatus,
                    p.EndTime,
                    p.UpdatedUserId,
                    p.UpdatedTime
                })
                .ExecuteCommandAsync();
            if (processUpdateCount == 0)
            {
                throw new BusinessException("流程状态更新失败。");
            }
            //记录流程日志
            await LogProcessOpAsync(processBefore, process, "Update", currUserId);
        }
        /// 
        /// 更新签证节点信息及状态
        /// 
        /// 签证节点更新数据传输对象
        /// 操作结果
        public async Task UpdateVisaNodeDetailsAsync(GroupProcessUpdateVisaNodeDetailsDto dto)
        {
            // 1. 获取并验证节点和流程
            var node = await _sqlSugar.Queryable()
                .FirstAsync(n => n.Id == dto.NodeId && n.IsDel == 0)
                ?? throw new BusinessException("当前节点不存在或已被删除。");
            var process = await _sqlSugar.Queryable()
                .FirstAsync(p => p.Id == node.ProcessId && p.IsDel == 0)
                ?? throw new BusinessException("当前流程不存在或已被删除。");
            if (process.ProcessType != GroupProcessType.Visa)
            {
                throw new BusinessException("当前流程节点不为签证流程,不可编辑。");
            }
            // 2. 检查签证子节点 字段信息是否全部填写
            var allSubNodesCompleted = dto.VisaSubNodes?.All(subNode => EntityExtensions.IsCompleted(subNode)) ?? false;
            // 2.1 存储更新前流程及节点信息
            var nodeBefore = new Grp_ProcessNode()
            {
                Id = node.Id,
                ProcessId = node.ProcessId,
                NodeName = node.NodeName,
                NodeOrder = node.NodeOrder,
                OverallStatus = node.OverallStatus,
                Operator = node.Operator,
                OperationTime = node.OperationTime,
                IsCurrent = node.IsCurrent,
            };
            var processBefore = new Grp_ProcessOverview()
            {
                Id = process.Id,
                GroupId = process.GroupId,
                ProcessOrder = process.ProcessOrder,
                ProcessType = process.ProcessType,
                OverallStatus = process.OverallStatus,
                StartTime = process.StartTime,
                EndTime = process.EndTime,
                UpdatedUserId = process.UpdatedUserId,
                UpdatedTime = process.UpdatedTime
            };
            // 3. 更新节点信息
            node.Remark = JsonConvert.SerializeObject(dto.VisaSubNodes);
            node.Operator = dto.CurrUserId;
            node.OperationTime = DateTime.Now;
            if (allSubNodesCompleted)
            {
                node.OverallStatus = ProcessStatus.Completed;
                process.OverallStatus = ProcessStatus.Completed;
                process.EndTime = DateTime.Now;
                process.UpdatedUserId = dto.CurrUserId;
                process.UpdatedTime = DateTime.Now;
                // 更新流程状态
                await _sqlSugar.Updateable(process)
                    .UpdateColumns(p => new
                    {
                        p.OverallStatus,
                        p.EndTime,
                        p.UpdatedUserId,
                        p.UpdatedTime
                    })
                    .ExecuteCommandAsync();
                //记录流程日志
                await LogProcessOpAsync(processBefore, process, "Update", dto.CurrUserId);
            }
            // 4. 保存节点更新
            await _sqlSugar.Updateable(node)
                .UpdateColumns(n => new
                {
                    n.Remark,
                    n.Operator,
                    n.OperationTime,
                    n.OverallStatus
                })
                .ExecuteCommandAsync();
            //记录节点日志
            await LogNodeOpAsync(nodeBefore, node, "Update", dto.CurrUserId);
            return new Result { Code = 200, Msg = "节点信息更新成功。" };
        }
        #region 操作日志
        /// 
        /// 记录流程操作日志
        /// 
        /// 操作前
        /// 操作后
        /// 操作类型(Create - 创建、Update - 更新、Complete - 完成)
        /// 操作人ID
        /// 异步任务
        public async Task LogProcessOpAsync(Grp_ProcessOverview before, Grp_ProcessOverview after,string opType, int operId)
        {
            var chgDetails = GetProcessChgDetails(before, after);
            var log = new Grp_ProcessLog
            {
                ProcessId = after?.Id ?? before?.Id,
                GroupId = after?.GroupId ?? before?.GroupId ?? 0,
                OpType = opType,
                OpDesc = GenerateProcessOpDesc(opType, before, after, chgDetails),
                BeforeData = before != null ? JsonConvert.SerializeObject(before, GetJsonSettings()) : null,
                AfterData = after != null ? JsonConvert.SerializeObject(after, GetJsonSettings()) : null,
                ChgFields = string.Join(",", chgDetails.Select(x => x.FieldName)),
                CreateUserId = operId
            };
            await _sqlSugar.Insertable(log).ExecuteCommandAsync();
        }
        /// 
        /// 记录节点操作日志
        /// 
        /// 操作前
        /// 操作后
        /// 操作类型(Create - 创建、Update - 更新、Start - 启动、Complete - 完成)
        /// 操作人ID
        /// 异步任务
        public async Task LogNodeOpAsync(Grp_ProcessNode before, Grp_ProcessNode after,string opType, int operId)
        {
            var chgDetails = GetNodeChgDetails(before, after);
            var log = new Grp_ProcessLog
            {
                NodeId = after?.Id ?? before?.Id,
                ProcessId = after?.ProcessId ?? before?.ProcessId,
                GroupId = 0, // 通过流程ID关联获取
                OpType = opType,
                OpDesc = GenerateNodeOpDesc(opType, before, after, chgDetails),
                BeforeData = before != null ? JsonConvert.SerializeObject(before, GetJsonSettings()) : null,
                AfterData = after != null ? JsonConvert.SerializeObject(before, GetJsonSettings()) : null,
                ChgFields = string.Join(",", chgDetails.Select(x => x.FieldName)),
                CreateUserId = operId
            };
            await _sqlSugar.Insertable(log).ExecuteCommandAsync();
        }
        /// 
        /// 获取流程变更详情
        /// 
        /// 变更前
        /// 变更后
        /// 变更详情
        private List GetProcessChgDetails(Grp_ProcessOverview before, Grp_ProcessOverview after)
        {
            var chgDetails = new List();
            if (before == null || after == null) return chgDetails;
            var props = typeof(Grp_ProcessOverview).GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .Where(p => p.CanRead && p.CanWrite && !IsExclField(p.Name));
            foreach (var prop in props)
            {
                var beforeVal = prop.GetValue(before);
                var afterVal = prop.GetValue(after);
                if (!Equals(beforeVal, afterVal))
                {
                    chgDetails.Add(new FieldChgDetail
                    {
                        FieldName = prop.Name,
                        BeforeValue = FormatVal(beforeVal),
                        AfterValue = FormatVal(afterVal)
                    });
                }
            }
            return chgDetails;
        }
        /// 
        /// 获取节点变更详情
        /// 
        /// 变更前
        /// 变更后
        /// 变更详情
        private List GetNodeChgDetails(Grp_ProcessNode before, Grp_ProcessNode after)
        {
            var chgDetails = new List();
            if (before == null || after == null) return chgDetails;
            var props = typeof(Grp_ProcessNode).GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .Where(p => p.CanRead && p.CanWrite && !IsExclField(p.Name));
            foreach (var prop in props)
            {
                var beforeVal = prop.GetValue(before);
                var afterVal = prop.GetValue(after);
                if (!Equals(beforeVal, afterVal))
                {
                    chgDetails.Add(new FieldChgDetail
                    {
                        FieldName = prop.Name,
                        BeforeValue = FormatVal(beforeVal),
                        AfterValue = FormatVal(afterVal)
                    });
                }
            }
            return chgDetails;
        }
        /// 
        /// 生成流程操作描述
        /// 
        /// 操作类型
        /// 操作前
        /// 操作后
        /// 变更详情
        /// 操作描述
        private string GenerateProcessOpDesc(string opType, Grp_ProcessOverview before,
            Grp_ProcessOverview after, List chgDetails)
        {
            var processType = after?.ProcessType ?? before?.ProcessType;
            var processName = GetProcessTypeName(processType);
            if (!chgDetails.Any())
            {
                return opType switch
                {
                    "Create" => $"创建流程:{processName}",
                    "Update" => $"更新流程:{processName} - 无变更",
                    //"Start" => $"启动流程:{processName}",
                    "Complete" => $"完成流程:{processName}",
                    //"Delete" => $"删除流程:{processName}",
                    _ => $"{opType}:{processName}"
                };
            }
            var chgDesc = string.Join("; ", chgDetails.Select(x =>
                $"{GetFieldDisplayName(x.FieldName)} ({x.BeforeValue} -> {x.AfterValue})"));
            return $"{GetOpTypeDisplay(opType)}:{processName} - {chgDesc}";
        }
        /// 
        /// 获取JSON序列化设置
        /// 
        /// JSON设置
        private static JsonSerializerSettings GetJsonSettings()
        {
            return new JsonSerializerSettings
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                NullValueHandling = NullValueHandling.Ignore,
                DateFormatString = "yyyy-MM-dd HH:mm:ss",
                Formatting = Formatting.None
            };
        }
        /// 
        /// 生成节点操作描述
        /// 
        /// 操作类型
        /// 操作前
        /// 操作后
        /// 变更详情
        /// 操作描述
        private string GenerateNodeOpDesc(string opType, Grp_ProcessNode before,
            Grp_ProcessNode after, List chgDetails)
        {
            var nodeName = after?.NodeName ?? before?.NodeName;
            if (!chgDetails.Any())
            {
                return opType switch
                {
                    "Create" => $"创建节点:{nodeName}",
                    "Update" => $"更新节点:{nodeName} - 无变更",
                    "Start" => $"启动节点:{nodeName}",
                    "Complete" => $"完成节点:{nodeName}",
                    //"Delete" => $"删除节点:{nodeName}",
                    _ => $"{opType}:{nodeName}"
                };
            }
            var chgDesc = string.Join("; ", chgDetails.Select(x =>
                $"{GetFieldDisplayName(x.FieldName)} ({x.BeforeValue} -> {x.AfterValue})"));
            return $"{GetOpTypeDisplay(opType)}:{nodeName} - {chgDesc}";
        }
        /// 
        /// 获取流程类型名称
        /// 
        /// 流程类型
        /// 流程名称
        private static string GetProcessTypeName(GroupProcessType? processType)
        {
            return processType switch
            {
                GroupProcessType.Invitation => "商邀报批",
                GroupProcessType.Visa => "签证",
                GroupProcessType.AirTicket => "机票",
                GroupProcessType.Hotel => "酒店",
                GroupProcessType.LocalGuide => "地接",
                GroupProcessType.FeeSettle => "费用结算",
                _ => "未知流程"
            };
        }
        /// 
        /// 获取操作类型显示
        /// 
        /// 操作类型
        /// 显示名称
        private static string GetOpTypeDisplay(string opType)
        {
            return opType switch
            {
                "Create" => "创建",
                "Update" => "更新",
                "Start" => "启动",
                "Complete" => "完成",
                "Delete" => "删除",
                "StatusChg" => "状态变更",
                _ => opType
            };
        }
        /// 
        /// 获取字段显示名称
        /// 
        /// 字段名
        /// 显示名称
        private string GetFieldDisplayName(string fieldName)
        {
            return fieldName switch
            {
                "OverallStatus" => "状态",
                "ProcessOrder" => "流程顺序",
                "StartTime" => "开始时间",
                "EndTime" => "结束时间",
                "NodeOrder" => "节点顺序",
                "NodeName" => "节点名称",
                "IsCurrent" => "当前节点",
                "Operator" => "操作人",
                "OperationTime" => "操作时间",
                _ => fieldName
            };
        }
        /// 
        /// 格式化值显示
        /// 
        /// 值
        /// 格式化值
        private string FormatVal(object value)
        {
            if (value == null) return "空";
            if (value is ProcessStatus status)
            {
                return status switch
                {
                    ProcessStatus.UnStarted => "未开始",
                    ProcessStatus.InProgress => "进行中",
                    ProcessStatus.Completed => "已完成",
                    _ => status.ToString()
                };
            }
            if (value is bool boolVal) return boolVal ? "是" : "否";
            if (value is DateTime dateVal) return dateVal.ToString("yyyy-MM-dd HH:mm");
            var strVal = value.ToString();
            return string.IsNullOrEmpty(strVal) ? "空" : strVal;
        }
        /// 
        /// 检查是否排除字段
        /// 
        /// 字段名
        /// 是否排除
        private bool IsExclField(string fieldName)
        {
            var exclFields = new List
            {
                "Id", "CreateTime", "CreateUserId", "UpdatedTime", "UpdatedUserId",
                "Nodes", "Process" // 导航属性
            };
            return exclFields.Contains(fieldName);
        }
        /// 
        /// 获取流程日志
        /// 
        /// 流程ID
        /// 日志列表
        public async Task> GetProcessLogsAsync(int processId)
        {
            return await _sqlSugar.Queryable()
                .Where(x => x.ProcessId == processId)
                .OrderByDescending(x => x.CreateTime)
                .ToListAsync();
        }
        /// 
        /// 获取团组流程日志
        /// 
        /// 团组ID
        /// 日志列表
        public async Task> GetGroupLogsAsync(int groupId)
        {
            return await _sqlSugar.Queryable()
                .Where(x => x.GroupId == groupId)
                .OrderByDescending(x => x.CreateTime)
                .ToListAsync();
        }
        #endregion
    }
}