using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common.Dto;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention;
using MassTransit;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace IRaCIS.Core.Infra.EFCore.Common
{
    public static class AuditOpt
    {
        public static readonly string Add = "Add";
        public static readonly string Update = "Update";
        public static readonly string Deleted = "Deleted";
    }

    /// <summary>
    /// 添加稽查稽查数据
    /// </summary>
    public class AuditingData : IAuditingData
    {

        /// <summary>
        /// 数据库对象o
        /// </summary>
        public IRaCISDBContext _dbContext { get; set; }

        /// <summary>
        /// 用户信息
        /// </summary>
        public IUserInfo _userInfo { get; set; }

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="userInfo"></param>
        public AuditingData(IRaCISDBContext dbContext, IUserInfo userInfo)
        {
            _dbContext = dbContext;
            _userInfo = userInfo;
            _userInfo.BatchId = _userInfo.BatchId == null ? NewId.NextGuid() : _userInfo.BatchId;
        }



        /// <summary>
        /// 特殊删除
        /// </summary>
        private List<Type> NodeleteTableTypes
        {
            get
            {
                return new List<Type>()
                {
                   typeof(TrialUser),
                   typeof(TrialSiteSurvey),
                   typeof(TrialSiteUser),
                   typeof(VisitStage),
                   typeof(TrialSite)
                };
            }
        }


        public string GetEntityAuditOpt(EntityEntry entityEntry)
        {
            if (entityEntry.State == EntityState.Added)
            {
                return AuditOpt.Add;
            }

            else if (entityEntry.State == EntityState.Deleted ||
                      (entityEntry.State == EntityState.Modified
                       && typeof(ISoftDelete).IsAssignableFrom(entityEntry.Entity.GetType())
                       && (bool)entityEntry.Entity.GetType().GetProperty(nameof(ISoftDelete.IsDeleted)).GetValue(entityEntry.Entity)
                       && entityEntry.State == EntityState.Modified
                       && !NodeleteTableTypes.Contains(entityEntry.Entity.GetType())
                       )
                     )
            {
                return AuditOpt.Deleted;
            }
            else
            {
                return AuditOpt.Update;
            }
        }

        /// <summary>
        /// 插入Add的实体
        /// </summary>
        /// <param name="entitys"></param>
        public async Task InsertAddEntitys(List<EntityEntry> entitys)
        {

            #region 区分

            // 项目
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(Trial)))
            {

                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as Trial;
                List<string> trialDics = new List<string>();
                var dictionaryIds = new List<Guid>();
                if (entity.TrialDicList == null || entity.TrialDicList.Count == 0)
                {
                    dictionaryIds = await this._dbContext.TrialDictionary.Where(x => x.TrialId == entity.Id && x.KeyName == "Criterion").Select(x => x.DictionaryId).ToListAsync();
                }
                else
                {
                    dictionaryIds = entity.TrialDicList.Select(x => x.DictionaryId).ToList();
                }

                trialDics = await this._dbContext.Dictionary.Where(x => dictionaryIds.Contains(x.Id)).Select(x => x.ValueCN).ToListAsync();

                await InsertInspection<Trial>(item.Entity as Trial, type, x => new InspectionConvertDTO()
                {
                    TrialId = x.Id,
                }, new
                {
                    TrialDicList = string.Join(",", trialDics)
                });
            }





            #endregion


            #region 已修改

            #region 阅片单元配置

            //系统阅片标准
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingQuestionCriterionSystem)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as ReadingQuestionCriterionSystem;


                await InsertInspection<ReadingQuestionCriterionSystem>(entity, type, x => new InspectionConvertDTO()
                {
                    IsDistinctionInterface = false

                });
            }
            //项目阅片标准
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingQuestionCriterionTrial)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as ReadingQuestionCriterionTrial;

                var isDistinctionInterface = false;

                //设置项目配置 肿瘤学配置 和阅片标准配置
                if (_userInfo.RequestUrl == "TrialConfig/setOncologySet" || _userInfo.RequestUrl == "TrialConfig/setTrialReadingCriterion")
                {
                    isDistinctionInterface = true;
                }


                await InsertInspection<ReadingQuestionCriterionTrial>(entity, type, x => new InspectionConvertDTO()
                {
                    IsDistinctionInterface = isDistinctionInterface,

                    ObjectRelationParentId = x.TrialId

                });
            }

            //系统标准问题
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingQuestionSystem)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as ReadingQuestionSystem;

                int? parentQuestionShowOrder = null;
                int? relavantQuestionShowOrder = null;

                if (entity.ParentId != null)
                {
                    parentQuestionShowOrder = await _dbContext.ReadingQuestionSystem.Where(t => t.Id == entity.ParentId).Select(t => t.ShowOrder).FirstOrDefaultAsync();

                }
                if (entity.RelevanceId != null)
                {
                    relavantQuestionShowOrder = await _dbContext.ReadingQuestionSystem.Where(t => t.Id == entity.RelevanceId).Select(t => t.ShowOrder).FirstOrDefaultAsync();

                }


                await InsertInspection<ReadingQuestionSystem>(entity, type, x => new InspectionConvertDTO()
                {
                    IsDistinctionInterface = false

                }, new { ParentQuestionShowOrder = parentQuestionShowOrder, RelavantQuestionShowOrder = relavantQuestionShowOrder });
            }
            //项目标准问题
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingQuestionTrial)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as ReadingQuestionTrial;


                var isDistinctionInterface = false;
                //重置仲裁规则
                if (_userInfo.RequestUrl == "ReadingImageTask/setTrialCriterionJudgeQuestionAnswerGroup")
                {
                    isDistinctionInterface = true;
                }


                int? parentQuestionShowOrder = null;
                int? relavantQuestionShowOrder = null;

                if (entity.ParentId != null)
                {
                    parentQuestionShowOrder = await _dbContext.ReadingQuestionSystem.Where(t => t.Id == entity.ParentId).Select(t => t.ShowOrder).FirstOrDefaultAsync();

                }
                if (entity.RelevanceId != null)
                {
                    relavantQuestionShowOrder = await _dbContext.ReadingQuestionSystem.Where(t => t.Id == entity.RelevanceId).Select(t => t.ShowOrder).FirstOrDefaultAsync();

                }


                await InsertInspection<ReadingQuestionTrial>(entity, type, x => new InspectionConvertDTO()
                {
                    IsDistinctionInterface = isDistinctionInterface,

                    ObjectRelationParentId = x.TrialId

                }, new { ParentQuestionShowOrder = parentQuestionShowOrder, RelavantQuestionShowOrder = relavantQuestionShowOrder });
            }

            //系统标准表格问题
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingTableQuestionSystem)))
            {

                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as ReadingTableQuestionSystem;

                int? dependQuestionShowOrder = null;
                int? parentQuestionShowOrder = null;
                int? relavantQuestionShowOrder = null;

                if (entity.ParentId != null)
                {
                    parentQuestionShowOrder = await _dbContext.ReadingQuestionSystem.Where(t => t.Id == entity.ParentId).Select(t => t.ShowOrder).FirstOrDefaultAsync();

                }
                if (entity.RelevanceId != null)
                {
                    relavantQuestionShowOrder = await _dbContext.ReadingQuestionSystem.Where(t => t.Id == entity.RelevanceId).Select(t => t.ShowOrder).FirstOrDefaultAsync();

                }
                if (entity.DependParentId != null)
                {
                    dependQuestionShowOrder = await _dbContext.ReadingQuestionSystem.Where(t => t.Id == entity.DependParentId).Select(t => t.ShowOrder).FirstOrDefaultAsync();

                }


                await InsertInspection<ReadingTableQuestionSystem>(entity, type, x => new InspectionConvertDTO()
                {
                    IsDistinctionInterface = false

                }, new { ParentQuestionShowOrder = parentQuestionShowOrder, RelavantQuestionShowOrder = relavantQuestionShowOrder, DependQuestionShowOrder = dependQuestionShowOrder });
            }
            //项目标准表格问题
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingTableQuestionTrial)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as ReadingTableQuestionTrial;

                int? dependQuestionShowOrder = null;
                int? parentQuestionShowOrder = null;
                int? relavantQuestionShowOrder = null;

                if (entity.ParentId != null)
                {
                    parentQuestionShowOrder = await _dbContext.ReadingQuestionSystem.Where(t => t.Id == entity.ParentId).Select(t => t.ShowOrder).FirstOrDefaultAsync();

                }
                if (entity.RelevanceId != null)
                {
                    relavantQuestionShowOrder = await _dbContext.ReadingQuestionSystem.Where(t => t.Id == entity.RelevanceId).Select(t => t.ShowOrder).FirstOrDefaultAsync();

                }
                if (entity.DependParentId != null)
                {
                    dependQuestionShowOrder = await _dbContext.ReadingQuestionSystem.Where(t => t.Id == entity.DependParentId).Select(t => t.ShowOrder).FirstOrDefaultAsync();
                }

                await InsertInspection<ReadingTableQuestionTrial>(entity, type, x => new InspectionConvertDTO()
                {
                    IsDistinctionInterface = false,

                    ObjectRelationParentId = x.TrialId

                }, new { ParentQuestionShowOrder = parentQuestionShowOrder, RelavantQuestionShowOrder = relavantQuestionShowOrder, DependQuestionShowOrder = dependQuestionShowOrder });
            }


            #endregion


            // 系统文件签署  父层级未记录稽查（系统文档初始数据）
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(SystemDocConfirmedUser)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as SystemDocConfirmedUser;
                var systemDocument = await _dbContext.SystemDocument.Where(x => x.Id == entity.SystemDocumentId).FirstOrDefaultAsync();
                await InsertInspection<SystemDocConfirmedUser>(entity, type, x => new InspectionConvertDTO()
                {
                    GeneralId = x.Id,

                    ObjectRelationParentId = x.SystemDocumentId

                }, new
                {

                    FileTypeId = systemDocument.FileTypeId,
                    Name = systemDocument.Name,
                    UploadTime = systemDocument.CreateTime,

                    CreateUserName = _userInfo.UserName,
                    UserType = _userInfo.UserTypeShortName,
                    IsSigned = true,// 是否签署  添加了就是签署了
                });
            }

            // 项目文件签署
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialDocUserTypeConfirmedUser)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as TrialDocUserTypeConfirmedUser;

                var trialDoc = await _dbContext.TrialDocument.Where(x => x.Id == entity.TrialDocumentId).FirstOrDefaultAsync();

                await InsertInspection<TrialDocUserTypeConfirmedUser>(entity as TrialDocUserTypeConfirmedUser, type, x => new InspectionConvertDTO()
                {
                    TrialId = trialDoc.TrialId,


                    ObjectRelationParentId = x.TrialDocumentId
                }, new
                {

                    UploadTime = trialDoc.CreateTime,

                    CreateUserName = _userInfo.UserName,
                    UserType = _userInfo.UserTypeShortName,
                    IsSigned = true
                });
            }


            //医学审核
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TaskMedicalReview)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as TaskMedicalReview;

                await InsertInspection<TaskMedicalReview>(entity, type, x => new InspectionConvertDTO()
                {
                    VisitTaskId = entity.VisitTaskId,

                    ObjectRelationParentId = entity.VisitTaskId,

                    ObjectRelationParentId2 = entity.MedicalManagerUserId
                });
            }

            //医学审核 问题答案
            if (entitys.Any(x => x.Entity.GetType() == typeof(ReadingMedicineQuestionAnswer)))
            {

                var type = AuditOpt.Add;

                var list = entitys.Where(x => x.Entity.GetType() == typeof(ReadingMedicineQuestionAnswer)).Select(t => t.Entity as ReadingMedicineQuestionAnswer);

                var questionIdList = list.Select(t => t.ReadingMedicineQuestionId).ToList();

                var questionNameList = await _dbContext.ReadingMedicineTrialQuestion.Where(x => questionIdList.Contains(x.Id)).Select(t => new { t.QuestionName, ReadingMedicineQuestionId = t.Id, t.ShowOrder }).ToListAsync();

                var firstEntity = list.FirstOrDefault();

                var cloneEntity = firstEntity.Clone();

                //保证Id 唯一
                cloneEntity.Id = IdentifierHelper.CreateGuid(firstEntity.VisitTaskId.ToString(), firstEntity.TaskMedicalReviewId.ToString());

                await InsertInspection(cloneEntity, type, x => new InspectionConvertDTO()
                {
                    VisitTaskId = x.VisitTaskId,

                    //byzhouhang
                    ObjectRelationParentId = x.TaskMedicalReviewId,
                }, new
                {
                    QuestionAnswerList = list.Join(questionNameList, t => t.ReadingMedicineQuestionId, u => u.ReadingMedicineQuestionId, (t, u) => new { t.Answer, u.QuestionName, u.ShowOrder }).OrderBy(t => t.ShowOrder).ToList(),
                });
            }


            //医学审核对话

            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingMedicalReviewDialog)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as ReadingMedicalReviewDialog;

                await InsertInspection<ReadingMedicalReviewDialog>(entity, type, x => new InspectionConvertDTO()
                {
                    VisitTaskId = entity.VisitTaskId,

                    ObjectRelationParentId = entity.TaskMedicalReviewId,

                });
            }


            //肿瘤学阅片结果

            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingOncologyTaskInfo)))
            {
                var type = AuditOpt.Add;

                var entity = item.Entity as ReadingOncologyTaskInfo;

                await InsertInspection<ReadingOncologyTaskInfo>(entity, type, x => new InspectionConvertDTO()
                {
                    VisitTaskId = entity.VisitTaskId,

                    ObjectRelationParentId = entity.VisitTaskId,

                });
            }


            #region 肿瘤学阅片结果 记录表格

            //if (entitys.Any(x => x.Entity.GetType() == typeof(ReadingOncologyTaskInfo)))
            //{
            //    var type = AuditOpt.Add;

            //    var oncologyAnswerList = entitys.Where(x => x.Entity.GetType() == typeof(ReadingOncologyTaskInfo)).Select(t => t.Entity as ReadingOncologyTaskInfo);

            //    var visitTaskIdList = oncologyAnswerList.Select(t => t.VisitTaskId).ToList();

            //    var visitTaskList = await _dbContext.VisitTask.Where(t => visitTaskIdList.Contains(t.Id)).Select(t => new { VisitTaskId = t.Id, t.TaskName, t.TaskBlindName, t.VisitTaskNum, t.SubjectId }).ToListAsync();



            //    var modifyVisitList = await _dbContext.ReadingGlobalTaskInfo.Where(t => visitTaskIdList.Contains(t.TaskId) && t.VisitTask.TaskState == TaskState.Effect).GroupBy(t => t.TaskId).Select(g => new
            //    {
            //        VisitTaskId = g.Key,
            //        GlobalResult = g.Select(c => new { c.Answer, c.QuestionId })
            //    }).ToListAsync();


            //    //var oncologyAnswerVisitList = visitTaskList.Join(oncologyAnswerList, t => t.VisitTaskId, u => u.VisitTaskId, (t, u) => new { t.VisitTaskId, t.TaskBlindName, t.TaskName, u.EvaluationReason, u.EvaluationResult }).ToList();

            //    var query = from answer in oncologyAnswerList
            //                join visitTask in visitTaskList on answer.VisitTaskId equals visitTask.VisitTaskId
            //                join modifyVisit in modifyVisitList on answer.VisitTaskId equals modifyVisit.VisitTaskId into cc
            //                from modifyVisit in cc.DefaultIfEmpty()
            //                select new
            //                {
            //                    visitTask.TaskBlindName,
            //                    visitTask.TaskName,
            //                    answer.EvaluationReason,
            //                    answer.EvaluationResult,
            //                    IsGlobalModify = modifyVisit != null,
            //                    Reason = modifyVisit != null ? modifyVisit.GlobalResult.Where(t => t.QuestionId == null).FirstOrDefault()?.Answer : String.Empty
            //                };
            //    var result = query.ToList();


            //    var oncologyAnswer = oncologyAnswerList.First();

            //    var cloneEntity = oncologyAnswer.Clone();

            //    cloneEntity.Id = NewId.NextGuid();

            //    await InsertInspection<ReadingOncologyTaskInfo>(oncologyAnswer, type, x => new InspectionConvertDTO()
            //    {
            //        VisitTaskId = oncologyAnswer.VisitTaskId,

            //        ObjectRelationParentId = oncologyAnswer.VisitTaskId,

            //    }, new { OncologyAnswerList = result });
            //}

            #endregion


            // 全局 阅片结果
            if (entitys.Any(x => x.Entity.GetType() == typeof(ReadingGlobalTaskInfo)))
            {
                //var type = AuditOpt.Add;

                //var list = entitys.Where(x => x.Entity.GetType() == typeof(ReadingGlobalTaskInfo)).Select(t => t.Entity as ReadingGlobalTaskInfo);


                //foreach (var group in list.GroupBy(t => t.TaskId))
                //{
                //    var questionAnswerList = group.Where(t => t.QuestionId != null).ToList();

                //    var reasonStr = group.Where(t => t.QuestionId == null).FirstOrDefault().Answer;

                //    var questionIdList = questionAnswerList.Select(t => t.QuestionId).ToList();

                //    var quesionList = await _dbContext.ReadingQuestionTrial.Where(t => questionIdList.Contains(t.Id)).Select(t => new { t.QuestionName, QuestionId = t.Id, t.ShowOrder }).OrderBy(t => t.ShowOrder).ToListAsync();


                //    var firstEntity = questionAnswerList.First();

                //    var cloneEntity = firstEntity.Clone();

                //    //保证Id 唯一
                //    cloneEntity.Id = IdentifierHelper.CreateGuid(firstEntity.GlobalTaskId.ToString(), firstEntity.TaskId.ToString(), firstEntity.Id.ToString());



                //    await InsertInspection<ReadingGlobalTaskInfo>(cloneEntity, type, x => new InspectionConvertDTO()
                //    {
                //        VisitTaskId = x.TaskId,

                //        ObjectRelationParentId = x.TaskId,

                //    }, new { Reason = reasonStr, QuestionAnswerList = questionAnswerList.Join(quesionList, t => t.QuestionId, u => u.QuestionId, (t, u) => new { t.Answer, u.QuestionName, u.ShowOrder }).OrderBy(t => t.ShowOrder).ToList() });
                //}






            }



            //任务
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(VisitTask)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as VisitTask;

                var obj = new object() { };

                //访视任务

                if (_userInfo.RequestUrl == "ReadingImageTask/SubmitVisitTaskQuestions" && entity.ReadingTaskState != ReadingTaskState.HaveSigned && type==AuditOpt.Update)
                {
                    //提交访视任务的时候 会多次更新同一个记录 只记录最后一次
                    return;
                }

                //裁判任务
                if (entity.JudgeResultTaskId != null && (_userInfo.RequestUrl == "ReadingImageTask/saveJudgeVisitTaskResult" || _userInfo.RequestUrl == "ReadingImageTask/saveJudgeVisitTaskResult"))
                {
                    var list = await _dbContext.VisitTask.Where(t => t.TaskState == TaskState.Effect && t.SubjectId == entity.SubjectId && t.VisitTaskNum == entity.VisitTaskNum).Select(t => new { t.Id, t.DoctorUser.FullName, t.ArmEnum }).OrderBy(t => t.ArmEnum).ToListAsync();

                    var r1 = list.First();
                    var r2 = list.Last();


                    obj = new { R1 = r1.FullName, R2 = r2.FullName, SelectResult = entity.ArmEnum == r1.ArmEnum ? "R1" : "R2" };
                }

                //肿瘤学任务
                if (entity.ReadingTaskState == ReadingTaskState.HaveSigned && _userInfo.RequestUrl == "ReadingImageTask/SubmitOncologyReadingInfo")
                {


                    var oncologyAnswerList = await _dbContext.ReadingOncologyTaskInfo.Where(t => t.OncologyTaskId == entity.Id).Select(t => new { t.VisitTask.TaskBlindName, t.VisitTask.TaskName, t.EvaluationReason, t.EvaluationResult, t.VisitTask.VisitTaskNum, VisitTaskId = t.VisitTask.Id }).ToListAsync();

                    var golbalTaskInfo = await _dbContext.VisitTask.Where(t => t.SubjectId == entity.SubjectId && t.ReadingCategory == ReadingCategory.Global && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == entity.IsAnalysisCreate && t.VisitTaskNum == (entity.VisitTaskNum - ReadingCommon.TaskNumDic[ReadingCategory.Oncology] + ReadingCommon.TaskNumDic[ReadingCategory.Global])).Select(t => new { GlobalTaskId = t.Id }).FirstNotNullAsync();


                    var globalResultList = await _dbContext.ReadingGlobalTaskInfo.Where(t => t.GlobalTaskId == golbalTaskInfo.GlobalTaskId).ToListAsync();

                    var modifyVisitList = globalResultList
                           .GroupBy(t => t.TaskId).Select(g => new
                           {
                               VisitTaskId = g.Key,
                               GlobalResult = g.Select(c => new { c.Answer, c.QuestionId })
                           }).ToList();

                    var query = from answer in oncologyAnswerList
                                join modifyVisit in modifyVisitList on answer.VisitTaskId equals modifyVisit.VisitTaskId into cc
                                from modifyVisit in cc.DefaultIfEmpty()
                                select new
                                {
                                    answer.TaskBlindName,
                                    answer.TaskName,
                                    answer.EvaluationReason,
                                    answer.EvaluationResult,
                                    IsGlobalModify = modifyVisit != null,
                                    Reason = modifyVisit != null ? modifyVisit.GlobalResult.Where(t => t.QuestionId == null).FirstOrDefault()?.Answer : String.Empty
                                };

                    var result = query.ToList();

                    obj = new { OncologyAnswerList = result };
                }

                //全局任务  
                if (entity.ReadingTaskState == ReadingTaskState.HaveSigned && _userInfo.RequestUrl == "ReadingImageTask/SubmitGlobalReadingInfo")
                {

                    var globalResultList = await _dbContext.ReadingGlobalTaskInfo.Where(t => t.GlobalTaskId == entity.Id).Select(t => new { VisitTaskId = t.TaskId, t.QuestionId, t.Answer, t.VisitTask.TaskBlindName, t.VisitTask.TaskName, t.TrialReadingQuestion.QuestionName }).ToListAsync();

                    var visitTaskIdList = globalResultList.Select(t => t.VisitTaskId).ToList();

                    var visitResultList = await _dbContext.ReadingTaskQuestionAnswer.Where(t => visitTaskIdList.Contains(t.VisitTaskId) && t.ReadingQuestionTrial.IsJudgeQuestion).Select(t => new { t.VisitTaskId, t.VisitTask.TaskBlindName, t.VisitTask.TaskName, t.VisitTask.VisitTaskNum, t.ReadingQuestionTrial.QuestionName, t.ReadingQuestionTrial.ShowOrder, t.Answer, t.ReadingQuestionTrialId })
                        .OrderBy(t => t.VisitTaskNum).ToListAsync();

                    var query = visitResultList.GroupBy(t => new { t.VisitTaskId, t.VisitTaskNum, t.TaskName, t.TaskBlindName }).Select(g => new
                    {
                        VisitTaskId = g.Key.VisitTaskId,
                        VisitTaskNum = g.Key.VisitTaskNum,
                        TaskName = g.Key.TaskName,
                        TaskBlindName = g.Key.TaskBlindName,

                        VisitQuestionAnswerList = g.OrderBy(t=>t.ShowOrder).Select(u => new { u.QuestionName, u.Answer }).ToList(),

                        GlobalQuestionAnswerList = g.OrderBy(t => t.ShowOrder).Select(u => new { u.QuestionName, Answer = globalResultList.Where(t => t.VisitTaskId == g.Key.VisitTaskId && t.QuestionId == u.ReadingQuestionTrialId).FirstOrDefault()?.Answer ?? String.Empty }).ToList(),

                        Reason = globalResultList.Where(t => t.VisitTaskId == g.Key.VisitTaskId && t.QuestionId == null).FirstOrDefault()?.Answer ?? String.Empty
                    });


                    var result = query.ToList();

                    obj = new { GlobalAnswerList = result };
                }


                await InsertInspection<VisitTask>(entity, type, x => new InspectionConvertDTO()
                {
                    VisitTaskId = x.Id,

                    IsDistinctionInterface = type == AuditOpt.Update ? true : false,

                    ObjectRelationParentId = entity.SourceSubjectVisitId != null ? entity.SourceSubjectVisitId : entity.SouceReadModuleId,

                    ObjectRelationParentId2 = entity.DoctorUserId

                }, obj);
            }



            // Qc 问题答案   
            if (entitys.Any(x => x.Entity.GetType() == typeof(TrialQCQuestionAnswer)))
            {
                var entityEntryList = entitys.Where(x => x.Entity.GetType() == typeof(TrialQCQuestionAnswer));

                var type = entityEntryList.All(t => t.State == EntityState.Added) ? AuditOpt.Add : AuditOpt.Update;


                var list = entityEntryList.Select(t => t.Entity as TrialQCQuestionAnswer);


                var firstEntity = list.FirstOrDefault();

                var trialQuestionIdList = list.Select(t => t.TrialQCQuestionConfigureId);

                var trialQuestionNameList = await _dbContext.TrialQCQuestionConfigure.Where(x => x.TrialId == firstEntity.TrialId).Select(t => new { t.QuestionName, TrialQCQuestionConfigureId = t.Id, t.ShowOrder }).ToListAsync();

                var beforeAnswerList = await _dbContext.TrialQCQuestionAnswer.Where(x => x.SubjectVisitId == firstEntity.SubjectVisitId && x.CurrentQCEnum == firstEntity.CurrentQCEnum && x.QCProcessEnum == firstEntity.QCProcessEnum)
                    .Select(u => new { u.TrialQCQuestionConfigureId, u.Answer }).ToListAsync();

                var answerList = list.Select(u => new { u.TrialQCQuestionConfigureId, u.Answer }).Union(beforeAnswerList).DistinctBy(t => t.TrialQCQuestionConfigureId);

                var cloneEntity = firstEntity.Clone();

                //保证Id 唯一
                cloneEntity.Id = IdentifierHelper.CreateGuid(firstEntity.SubjectVisitId.ToString(), ((int)firstEntity.QCProcessEnum).ToString(), ((int)firstEntity.CurrentQCEnum).ToString());

                await InsertInspection(cloneEntity, type, x => new InspectionConvertDTO()
                {
                    SubjectVisitId = x.SubjectVisitId,

                    //byzhouhang
                    ObjectRelationParentId = x.SubjectVisitId,
                }, new
                {
                    QcQuestionAnswerList = answerList.Join(trialQuestionNameList, t => t.TrialQCQuestionConfigureId, u => u.TrialQCQuestionConfigureId, (t, u) => new { t.Answer, u.QuestionName, u.ShowOrder }).OrderBy(t => t.ShowOrder).ToList(),
                });




                #region OLd
                //var entitylist = entitys.Where(x => x.Entity.GetType() == typeof(TrialQCQuestionAnswer)).Select(x => x.Entity as TrialQCQuestionAnswer).ToList();
                //var firstEntity = entitylist.FirstOrDefault();
                //var subjectVisit = await _dbContext.SubjectVisit.Where(x => x.Id == firstEntity.SubjectVisitId).FirstOrDefaultAsync();
                //subjectVisit = subjectVisit ?? new SubjectVisit();
                //if (type == "Add")
                //{


                //    await InsertInspection(firstEntity, type, answer => new InspectionConvertDTO()
                //    {
                //        SiteId = subjectVisit.SiteId,
                //        SubjectId = subjectVisit.SubjectId,
                //        SubjectVisitName = subjectVisit.VisitName,
                //        TrialId = subjectVisit.TrialId,
                //        SubjectVisitId = subjectVisit.Id,

                //        //GeneralId = subjectVisit.Id,
                //        //byzhouhang
                //        ObjectRelationParentId = subjectVisit.Id,
                //    }, new
                //    {
                //        QcQuestionAnswerCommands = await Getdata(entitylist),
                //    });
                //}
                //else if (type == "Update")
                //{

                //    var questionIds = entitylist.Where(x => x.SubjectVisitId == subjectVisit.Id).Select(x => x.Id).ToList();
                //    var createUserId = entitylist.Select(x => x.CreateUserId).FirstOrDefault();
                //    var noUpdateData = _dbContext.TrialQCQuestionAnswer.Where(x => x.CreateUserId == createUserId && x.SubjectVisitId == subjectVisit.Id && !questionIds.Contains(x.Id)).ToList();
                //    entitylist.AddRange(noUpdateData);

                //    await InsertInspection(firstEntity, type, answer => new InspectionConvertDTO()
                //    {
                //        SiteId = subjectVisit.SiteId,
                //        SubjectId = subjectVisit.SubjectId,
                //        SubjectVisitName = subjectVisit.VisitName,
                //        TrialId = subjectVisit.TrialId,
                //        SubjectVisitId = subjectVisit.Id,

                //        //GeneralId = subjectVisit.Id,
                //        //byzhouhang
                //        ObjectRelationParentId = subjectVisit.Id,
                //    }, new
                //    {
                //        QcQuestionAnswerCommands = await Getdata(entitylist),
                //    });


                //}

                //async Task<List<AnswerDto>> Getdata(List<TrialQCQuestionAnswer> questionAnswers)
                //{
                //    var ids = questionAnswers.Select(x => x.TrialQCQuestionConfigureId).ToList();
                //    var trialQCQuestionConfigureDatas = await _dbContext.TrialQCQuestionConfigure.Where(x => ids.Contains(x.Id)).ToListAsync();
                //    var collect = questionAnswers.GroupJoin(trialQCQuestionConfigureDatas, one => one.TrialQCQuestionConfigureId, two => two.Id, (x, y) => new { one = x, two = y })
                //      .SelectMany(a => a.two.DefaultIfEmpty(), (c, d) => new { c = c.one, d })
                //      .OrderBy(x => x.d.ShowOrder)
                //      .Select(o => new AnswerDto()
                //      {
                //          QuestionName = o.d.QuestionName,
                //          Answer = o.c.Answer,
                //      }).ToList();
                //    return collect;
                //}
                #endregion





            }



            //QC 质疑
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(QCChallenge)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as QCChallenge;

                await InsertInspection<QCChallenge>(entity, type, x => new InspectionConvertDTO()
                {
                    SubjectVisitId = x.SubjectVisitId,

                    ObjectRelationParentId = x.SubjectVisitId
                }, new
                {

                    IsOverTime = entity.IsClosed ? entity.ClosedTime > entity.DeadlineTime : DateTime.Now > entity.DeadlineTime,
                });
            }

            // 质疑 对话
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(QCChallengeDialog)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as QCChallengeDialog;

                await InsertInspection<QCChallengeDialog>(entity, type, x => new InspectionConvertDTO()
                {

                    SubjectVisitId = x.SubjectVisitId,


                    //byzhouhang
                    ObjectRelationParentId = entity.QCChallengeId,

                    IsDistinctionInterface = false

                });
            }
            //一致性核查 对话
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(CheckChallengeDialog)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as CheckChallengeDialog;
                //var subjectvisit = await _dbContext.SubjectVisit.Where(x => x.Id == entity.SubjectVisitId).FirstOrDefaultAsync();
                //subjectvisit = subjectvisit ?? new SubjectVisit();
                //var reason = string.Empty;

                //switch (_userInfo.RequestUrl.ToLower())
                //{
                //    case "qcoperation/closecheckchallenge":
                //        reason = entity.TalkContent.Substring(entity.TalkContent.LastIndexOf(':') + 1);
                //        break;
                //}
                await InsertInspection<CheckChallengeDialog>(entity, type, x => new InspectionConvertDTO()
                {

                    SubjectVisitId = x.SubjectVisitId,

                    //byzhouhang
                    IsDistinctionInterface = false,

                    ObjectRelationParentId = entity.SubjectVisitId,
                }
                //, new
                //{
                //    CheckState = subjectvisit.CheckState,
                //    RequestBackState = subjectvisit.RequestBackState,
                //    CheckChallengeState = subjectvisit.CheckChallengeState,
                //}
                );
            }


            // 一致性核查文件  是否需要单独一个表记录？
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ConsistencyCheckFile)))
            {
                var type = GetEntityAuditOpt(item);

                await InsertInspection<ConsistencyCheckFile>(item.Entity as ConsistencyCheckFile, type, x => new InspectionConvertDTO()
                {
                    ObjectRelationParentId = x.TrialId

                });
            }

            // 中心调研表
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialSiteSurvey)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as TrialSiteSurvey;
                if (entity.TrialSite == null)
                {
                    entity.TrialSite = await _dbContext.TrialSite.Where(x => x.SiteId == entity.SiteId && x.TrialId == entity.TrialId).FirstOrDefaultAsync();
                }

                if (entity.PreliminaryUser == null)
                {
                    entity.PreliminaryUser = await _dbContext.User.Where(x => x.Id == entity.PreliminaryUserId).FirstOrDefaultAsync();
                }

                if (entity.ReviewerUser == null)
                {
                    entity.ReviewerUser = await _dbContext.User.Where(x => x.Id == entity.ReviewerUserId).FirstOrDefaultAsync();
                }

                await InsertInspection<TrialSiteSurvey>(item.Entity as TrialSiteSurvey, type, x => new InspectionConvertDTO()
                {
                    ObjectRelationParentId = entity.TrialSite.Id,
                }, new
                {

                    //TrialSiteCode = entity.TrialSite.TrialSiteCode,
                    //TrialSiteAliasName = entity.TrialSite.TrialSiteAliasName,
                    //Phone = entity.Phone,
                    //Email = entity.Email,


                    PreliminaryUser = entity.PreliminaryUser == null ? "" : entity.PreliminaryUser.FullName,
                    ReviewerUser = entity.ReviewerUser == null ? "" : entity.ReviewerUser.FullName,

                });
            }



            // 既往手术史
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(PreviousSurgery)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as PreviousSurgery;

                await InsertInspection<PreviousSurgery>(entity, type, x => new InspectionConvertDTO()
                {
                    IsDistinctionInterface = false,

                    SubjectVisitId = x.SubjectVisitId,

                    ObjectRelationParentId = x.SubjectVisitId,

                    ObjectRelationParentId2 = x.ClinicalDataTrialSetId,

                }, new
                {
                    Type = ClinicalFileType.PreviousSurgery
                });
            }

            // 既往放疗史
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(PreviousHistory)))
            {

                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as PreviousHistory;

                await InsertInspection<PreviousHistory>(entity, type, x => new InspectionConvertDTO()
                {


                    IsDistinctionInterface = false,

                    SubjectVisitId = x.SubjectVisitId,

                    ObjectRelationParentId2 = x.ClinicalDataTrialSetId,

                    ObjectRelationParentId = x.SubjectVisitId,
                }, new
                {
                    Type = ClinicalFileType.PreviousHistory
                });
            }

            // 其他治疗史
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(PreviousOther)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as PreviousOther;

                await InsertInspection<PreviousOther>(entity, type, x => new InspectionConvertDTO()
                {

                    IsDistinctionInterface = false,

                    SubjectVisitId = x.SubjectVisitId,

                    ObjectRelationParentId2 = x.ClinicalDataTrialSetId,

                    ObjectRelationParentId = x.SubjectVisitId,
                }, new
                {
                    Type = ClinicalFileType.PreviousOther
                });
            }





            //系统文件
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(SystemDocument)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as SystemDocument;

                List<Guid> needConfirmedUserTypeIdList = new List<Guid>();

                if (entity.NeedConfirmedUserTypeList == null)
                {
                    needConfirmedUserTypeIdList = await _dbContext.SystemDocNeedConfirmedUserType.Where(x => x.SystemDocumentId == entity.Id).Select(t => t.NeedConfirmUserTypeId).ToListAsync();
                }
                else
                {
                    needConfirmedUserTypeIdList = entity.NeedConfirmedUserTypeList.Select(t => t.NeedConfirmUserTypeId).ToList();
                }


                var userTypeNameList = await _dbContext.UserType.Where(x => needConfirmedUserTypeIdList.Contains(x.Id)).Select(x => x.UserTypeShortName).ToListAsync();
                var userTypeName = string.Join(",", userTypeNameList);
                await InsertInspection<SystemDocument>(entity, type, x => new InspectionConvertDTO()
                {
                    IsDistinctionInterface = false
                }, new
                {
                    NeedConfirmedUserType = userTypeName,
                });
            }

            // 项目文档
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialDocument)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as TrialDocument;

                List<Guid> needConfirmedUserTypeIdList = new List<Guid>();

                if (entity.NeedConfirmedUserTypeList == null)
                {
                    needConfirmedUserTypeIdList = await _dbContext.TrialDocNeedConfirmedUserType.Where(x => x.TrialDocumentId == entity.Id).Select(t => t.NeedConfirmUserTypeId).ToListAsync();
                }
                else
                {
                    needConfirmedUserTypeIdList = entity.NeedConfirmedUserTypeList.Select(t => t.NeedConfirmUserTypeId).ToList();
                }

                var usertypeNames = await _dbContext.UserType.Where(x => needConfirmedUserTypeIdList.Contains(x.Id)).Select(x => x.UserTypeShortName).ToListAsync();
                var usertypeName = string.Join(",", usertypeNames);
                await InsertInspection<TrialDocument>(entity, type, x => new InspectionConvertDTO()
                {
                    IsDistinctionInterface = false,
                    ObjectRelationParentId = x.TrialId
                },
                new
                {
                    NeedConfirmedUserType = usertypeName,
                });


            }

            //系统  Qc 问题
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(QCQuestion)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as QCQuestion;

                int? parentQuestionOrder = null;
                string parentQuestionName = string.Empty;

                if (entity.ParentId != null)
                {
                    var question = await _dbContext.QCQuestionConfigure.Where(x => x.Id == entity.ParentId).Select(x => new { x.Id, x.ShowOrder, x.QuestionName }).FirstOrDefaultAsync();

                    parentQuestionOrder = question?.ShowOrder;
                    parentQuestionName = question?.QuestionName;

                }


                await InsertInspection<QCQuestion>(entity, type, x => new InspectionConvertDTO()
                {
                    IsDistinctionInterface = false

                }, new
                {
                    ParentQuestionName = parentQuestionName,
                    ParentQuestionOrder = parentQuestionOrder
                });
            }

            // 项目QC问题
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialQCQuestion)))
            {

                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as TrialQCQuestion;

                int? parentQuestionOrder = null;
                string parentQuestionName = string.Empty;

                if (entity.ParentId != null)
                {
                    var question = entitys.Where(x => x.Entity.GetType() == typeof(TrialQCQuestion)).Select(t => t.Entity as TrialQCQuestion).Select(x => new { x.Id, x.ShowOrder, x.QuestionName }).FirstOrDefault(t => t.Id == entity.ParentId);

                    question = question ?? await _dbContext.TrialQCQuestionConfigure.Where(x => x.Id == entity.ParentId).Select(x => new { x.Id, x.ShowOrder, x.QuestionName }).FirstOrDefaultAsync();


                    parentQuestionOrder = question?.ShowOrder;
                    parentQuestionName = question?.QuestionName;

                }


                await InsertInspection<TrialQCQuestion>(entity, type, x => new InspectionConvertDTO()
                {
                    ObjectRelationParentId = x.TrialId,
                    IsDistinctionInterface = false
                }, new
                {
                    ParentQuestionName = parentQuestionName,
                    ParentQuestionOrder = parentQuestionOrder
                });
            }

            //系统 医学审核问题
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingMedicineSystemQuestion)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as ReadingMedicineSystemQuestion;

                var parentQuestionName = string.Empty;
                if (entity.ParentId != null)
                {
                    parentQuestionName = await _dbContext.ReadingMedicineSystemQuestion.Where(x => x.Id == entity.ParentId).Select(x => x.QuestionName).FirstOrDefaultAsync();
                }

                await InsertInspection<ReadingMedicineSystemQuestion>(entity, type, x => new InspectionConvertDTO()
                {
                    IsDistinctionInterface = false,
                }, new { ParentQuestionName = parentQuestionName });
            }

            //项目医学审核问题
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingMedicineTrialQuestion)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as ReadingMedicineTrialQuestion;

                var parentQuestionName = string.Empty;
                if (entity.ParentId != null)
                {
                    parentQuestionName = await _dbContext.ReadingMedicineTrialQuestion.Where(x => x.Id == entity.ParentId).Select(x => x.QuestionName).FirstOrDefaultAsync();
                }

                await InsertInspection<ReadingMedicineTrialQuestion>(entity, type, x => new InspectionConvertDTO()
                {
                    IsDistinctionInterface = false,
                    ObjectRelationParentId = x.TrialId

                }, new { ParentQuestionName = parentQuestionName });
            }


            // 签名模板
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(SystemBasicData)))
            {
                var type = GetEntityAuditOpt(item);

                await InsertInspection<SystemBasicData>(item.Entity as SystemBasicData, type, x => new InspectionConvertDTO()
                {
                    IsDistinctionInterface = false
                });
            }



            // 项目中心  Site未稽查
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialSite)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as TrialSite;
                if (entity.Site == null)
                {
                    entity.Site = await _dbContext.Site.Where(x => x.Id == entity.SiteId).FirstOrDefaultAsync();
                }
                await InsertInspection<TrialSite>(entity, type, x => new InspectionConvertDTO()
                {
                    TrialId = x.TrialId,

                    ObjectRelationParentId = x.TrialId
                }, new
                {
                    //兼容之前的配置  冗余该字段
                    SiteCode = entity.TrialSiteCode,

                    //Site  没记录稽查 必须查询存
                    SiteName = entity.Site.SiteName,
                    City = entity.Site.City,
                    Country = entity.Site.Country,
                });
            }



            // 项目人员
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialUser)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as TrialUser;
                //var user = await _dbContext.Users.Include(x => x.UserTypeRole).FirstOrDefaultAsync(x => x.Id == entity.UserId);
                await InsertInspection<TrialUser>(entity, type, x => new InspectionConvertDTO
                {
                    IsDistinctionInterface= type == AuditOpt.Update ? true : false,
                    TrialId = x.TrialId,
                    ObjectRelationParentId = x.TrialId,
                    ObjectRelationParentId2 = x.UserId,
                });
            }


            // 项目中心人员
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TrialSiteUser)))
            {

                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as TrialSiteUser;


                if (entity.TrialSite == null)
                {
                    entity.TrialSite = await _dbContext.TrialSite.Where(x => x.TrialId == entity.TrialId && x.SiteId == entity.SiteId).IgnoreQueryFilters().FirstOrDefaultAsync();
                }

                await InsertInspection<TrialSiteUser>(item.Entity as TrialSiteUser, type, x => new InspectionConvertDTO
                {
                    TrialId = x.TrialId,
                    ObjectRelationParentId = entity.TrialSite.Id,
                    ObjectRelationParentId2 = x.UserId,
                });
            }


            // 受试者
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(Subject)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as Subject;
                var finalSubjectVisitName = await _dbContext.SubjectVisit.AsNoTracking().Where(x => x.Id == entity.FinalSubjectVisitId && entity.FinalSubjectVisitId != null).Select(x => x.VisitName).FirstOrDefaultAsync();

                //var trialSiteCode = await _dbContext.TrialSite.Where(t => t.TrialId == entity.TrialId && t.SiteId == entity.SiteId).Select(t => t.TrialSiteCode).FirstOrDefaultAsync();

                var trialSiteId = await _dbContext.TrialSite.Where(t => t.TrialId == entity.TrialId && t.SiteId == entity.SiteId).Select(t => t.Id).FirstOrDefaultAsync();

                await InsertInspection<Subject>(entity, type, x => new InspectionConvertDTO()
                {
                    SubjectId = x.Id,
                    SiteId = x.SiteId,

                    //项目的信息 找离的最近的项目稽查信息
                    ObjectRelationParentId = trialSiteId,
                }, new
                {
                    FinalSubjectVisitName = finalSubjectVisitName,

                    //变换名称   兼容之前做的稽查  冗余
                    SubjectCode = entity.Code,
                });
            }

            // 访视计划
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(VisitStage)))
            {

                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as VisitStage;

                await InsertInspection<VisitStage>(item.Entity as VisitStage, type, x => new InspectionConvertDTO()
                {
                    ObjectRelationParentId = x.TrialId

                });

                #region Old
                //var visitPlanStatus = await this._dbContext.Trial.Where(x => x.Id == entity.TrialId).Select(x => x.VisitPlanConfirmed).FirstOrDefaultAsync();
                //if (type == "Add")
                //{
                //    visitPlanStatus = false;
                //}
                //await InsertInspection<VisitStage>(item.Entity as VisitStage, type, x => new InspectionConvertDTO()
                //{
                //    ObjectRelationParentId = x.TrialId

                //}, new
                //{
                //    VisitPlanStatus = visitPlanStatus,
                //});
                #endregion

            }

            // 访视
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(SubjectVisit)))
            {

                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as SubjectVisit;

                await InsertInspection<SubjectVisit>(item.Entity as SubjectVisit, type, x => new InspectionConvertDTO()
                {
                    //Subject的信息 找离的最近的Subject稽查信息
                    ObjectRelationParentId = x.SubjectId,

                    SubjectId = x.SubjectId,
                    SubjectVisitId = x.Id,
                    SiteId = x.SiteId,

                },
                //兼容之前的配置名 
                new { SubjectVisitName = entity.VisitName }
                );
            }

            // Dicom
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(DicomStudy)))
            {
                var type = GetEntityAuditOpt(item);

                await InsertInspection<DicomStudy>(item.Entity as DicomStudy, type, x => new InspectionConvertDTO()
                {
                    ObjectRelationParentId = x.SubjectVisitId
                });
            }

            // 序列
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(DicomSeries)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as DicomSeries;

                await InsertInspection<DicomSeries>(item.Entity as DicomSeries, type, x => new InspectionConvertDTO()
                {
                    ObjectRelationParentId = x.StudyId
                }
                );
            }


            // 非Dicom
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(NoneDicomStudy)))
            {

                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as NoneDicomStudy;

                await InsertInspection<NoneDicomStudy>(item.Entity as NoneDicomStudy, type, x => new InspectionConvertDTO()
                {
                    ObjectRelationParentId = x.SubjectVisitId,

                });
            }

            //if(entitys.Any(x => x.Entity.GetType() == typeof(NoneDicomStudyFile)))
            //{
            //    var list = entitys.Where(x => x.Entity.GetType() == typeof(NoneDicomStudyFile)).Select(t=>t.Entity);

            //    var first = list.First() as NoneDicomStudyFile;

            //    if(first.NoneDicomStudy == null)
            //    {
            //        first.NoneDicomStudy = _dbContext.NoneDicomStudy.Find(first.NoneDicomStudyId);
            //    }

            //    await InsertInspection<NoneDicomStudyFile>(first, type, x => new InspectionConvertDTO()
            //    {
            //        GeneralId=first.NoneDicomStudyId,

            //        SubjectVisitId= first.NoneDicomStudy.SubjectVisitId,


            //        ObjectRelationParentId = x.NoneDicomStudyId,

            //    });

            //}




            #region 阅片人入组


            //阅片人入组   父层级未记录稽查（医生）
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(Enroll)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as Enroll;
                var doctor = await _dbContext.Doctor.FirstOrDefaultAsync(x => x.Id == entity.DoctorId);
                var readingCategoryList = await _dbContext.EnrollReadingCategory.Where(x => x.EnrollId == entity.Id).Select(t => t.ReadingCategory).ToListAsync();
                await InsertInspection<Enroll>(item.Entity as Enroll, type, x => new InspectionConvertDTO()
                {
                    ObjectRelationParentId = x.TrialId
                }, new
                {
                    //父层级的数据  暂时没有记录稽查  所以这里必须查
                    Name = doctor.FullName,
                    ChineseName = doctor.ChineseName,
                    Email = doctor.EMail,
                    IsUploadedACKSOW = entity.AttachmentId != Guid.Empty,

                    //子层级的数据 记录到父层级 必须查询  不然找上一条时数据不准
                    ReadingCategoryList = readingCategoryList
                });
            }

            //独立阅片人 设置阅片类型   这里对于操作人 不区分 添加 编辑 删除    只有设置（相当于更新）

            if (entitys.Any(x => x.Entity.GetType() == typeof(EnrollReadingCategory)))
            {
                var type = AuditOpt.Update;

                var addList = entitys.Where(x => x.Entity.GetType() == typeof(EnrollReadingCategory) && x.State == EntityState.Added).Select(t => t.Entity as EnrollReadingCategory).ToList();
                var deleteList = entitys.Where(x => x.Entity.GetType() == typeof(EnrollReadingCategory) && x.State == EntityState.Deleted).Select(t => t.Entity as EnrollReadingCategory).ToList();

                var first = addList.Union(deleteList).FirstOrDefault();

                var enrollId = first.EnrollId;

                Guid? trialId = Guid.Empty;

                if (first.Enroll != null)
                {
                    trialId = first.Enroll.TrialId;
                }
                else
                {
                    trialId = await _dbContext.Enroll.Where(x => x.Id == enrollId).Select(t => t.TrialId).FirstOrDefaultAsync();
                }


                await InsertInspection<EnrollReadingCategory>(first, type, x => new InspectionConvertDTO()
                {
                    //GeneralId  和ObjectRelationParentId 一样  会成环  所以查询的时候 需要排除自身 
                    GeneralId = enrollId,

                    TrialId = trialId,

                    ObjectRelationParentId = enrollId,

                    IsDistinctionInterface = false
                }, new
                {
                    ReadingCategoryList = addList.Select(t => t.ReadingCategory).ToList(),
                });
            }

            #endregion


            #region 阅片期临床数据



            //系统临床数据配置

            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ClinicalDataSystemSet)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as ClinicalDataSystemSet;

                await InsertInspection<ClinicalDataSystemSet>(entity, type, x => new InspectionConvertDTO()
                {
                    IsDistinctionInterface = false,
                });
            }



            //项目临床数据配置
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ClinicalDataTrialSet)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as ClinicalDataTrialSet;

                await InsertInspection<ClinicalDataTrialSet>(entity, type, x => new InspectionConvertDTO()
                {
                    IsDistinctionInterface = false,
                    ObjectRelationParentId = entity.TrialId,
                });
            }

            // CRC  PM 临床数据
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingClinicalData)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as ReadingClinicalData;

                await InsertInspection<ReadingClinicalData>(item.Entity as ReadingClinicalData, type, x => new InspectionConvertDTO()
                {

                    IsDistinctionInterface = type == AuditOpt.Update ? true : false,

                    SubjectVisitId = x.IsVisit ? x.ReadingId : null,

                    ObjectRelationParentId = entity.ClinicalDataTrialSetId,
                });
            }

            //阅片期计划
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingPeriodSet)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as ReadingPeriodSet;

                var siteCodes = string.Empty;
                if (entity.ReadingScope == ReadingScopeEnum.Site)
                {
                    var siteIds = entity.ReadingPeriodSites.Select(t => t.SiteId).ToList();
                    var nameList = _dbContext.TrialSite.Where(c => c.TrialId == entity.TrialId && siteIds.Contains(c.SiteId)).Select(t => t.TrialSiteCode).ToList();

                    siteCodes = String.Join(',', nameList);
                }

                await InsertInspection<ReadingPeriodSet>(item.Entity as ReadingPeriodSet, type, x => new InspectionConvertDTO()
                {
                    ObjectRelationParentId = x.VisitStageId

                }, new
                {
                    SiteCodes = siteCodes
                });
            }

            #region 阅片期临时数据不记录
            //foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadingPeriodPlan)))
            //{
            //    var entity = item.Entity as ReadingPeriodPlan;

            //    if (entity.ReadingPeriodSet == null)
            //    {
            //        entity.ReadingPeriodSet = _dbContext.ReadingPeriodSet.Find(entity.ReadingPeriodSetId);
            //    }

            //    await InsertInspection<ReadingPeriodPlan>(item.Entity as ReadingPeriodPlan, type, x => new InspectionConvertDTO()
            //    {
            //        GeneralId = x.Id,
            //        SubjectVisitId = x.SubjectVisitId,
            //    }, new
            //    {
            //        entity.ReadingPeriodSet.ReadingPeriodName,
            //        entity.ReadingPeriodSet.EffectOfTime,
            //        entity.ReadingPeriodSet.ExpirationDate
            //    });
            //}

            #endregion


            //阅片期
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(ReadModule)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as ReadModule;

                await InsertInspection<ReadModule>(item.Entity as ReadModule, type, x => new InspectionConvertDTO()
                {
                    ObjectRelationParentId = entity.SubjectVisitId,

                    SubjectVisitId = x.SubjectVisitId,
                    IsDistinctionInterface = false,
                });
            }


            #endregion


            #region 阅片

            //用户添加
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(User)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as User;

                await InsertInspection<User>(entity, type, x => new InspectionConvertDTO()
                {
                    IsDistinctionInterface = false
                }, new
                {
                    UserRealName = entity.FullName,
                }
                );
            }



            //分配规则
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TaskAllocationRule)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as TaskAllocationRule;

                await InsertInspection<TaskAllocationRule>(entity, type, x => new InspectionConvertDTO()
                {
                    IsDistinctionInterface = false,

                    ObjectRelationParentId = entity.EnrollId,

                    ObjectRelationParentId2 = entity.DoctorUserId

                });
            }

            //  suject  医生绑定关系
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(SubjectUser)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as SubjectUser;

                await InsertInspection<SubjectUser>(entity, type, x => new InspectionConvertDTO()
                {
                    IsDistinctionInterface = false,

                    ObjectRelationParentId = entity.SubjectId,

                    ObjectRelationParentId2 = entity.DoctorUserId

                }, new { ArmToTask = entity.ArmEnum });
            }



            //申请重阅记录表
            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(VisitTaskReReading)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as VisitTaskReReading;

                await InsertInspection<VisitTaskReReading>(entity, type, x => new InspectionConvertDTO()
                {
                    VisitTaskId = entity.OriginalReReadingTaskId,

                    Reason = entity.RequestReReadingReason,

                    ObjectRelationParentId = entity.OriginalReReadingTaskId,

                });
            }


            //一致性分析规则

            foreach (var item in entitys.Where(x => x.Entity.GetType() == typeof(TaskConsistentRule)))
            {
                var type = GetEntityAuditOpt(item);

                var entity = item.Entity as TaskConsistentRule;

                await InsertInspection<TaskConsistentRule>(entity, type, x => new InspectionConvertDTO()
                {
                    ObjectRelationParentId = entity.TrialId
                });
            }



            #endregion


            #endregion





        }

        /// <summary>
        /// 插入稽查实体
        /// </summary>
        /// <typeparam name="T">泛型</typeparam>
        /// <param name="data">数据</param>
        /// <param name="type">类型</param>
        /// <param name="expression">表达式</param>
        /// <param name="otherItem">其他对象</param>
        /// <returns></returns>
        public async Task InsertInspection<T>(T entityObj, string type, Expression<Func<T, InspectionConvertDTO>> expression = null, object otherItem = null) where T : Entity
        {

            InspectionConvertDTO inspection = new InspectionConvertDTO();


            if (expression != null)
            {
                var f = expression.Compile();

                inspection = f(entityObj);
            }

            //避免重复赋值  有些特殊的GeneralId  
            var generalId = (inspection.GeneralId != null && inspection.GeneralId != Guid.Empty) ? inspection.GeneralId : entityObj.Id;
            inspection.GeneralId = generalId;

            inspection.Identification = await GetInspectionRecordIdentificationAsync(inspection, entityObj, type, inspection.IsDistinctionInterface);

            //将实体对象属性 映射到稽查实体
            MapEntityPropertyToAuditEntity(entityObj, inspection);

            //var generalData = await GetInspectionGeneralDataAsync(inspection);

            var generalData = await GetInspectionGeneralGuidAsync(inspection);

            //不可少  因为稽查实体可能某些Id没有 
            MapEntityPropertyToAuditEntity(generalData, inspection);

            #region 处理标识

            var from = await _dbContext.FrontAuditConfig.FirstOrDefaultAsync(x => x.Identification == inspection.Identification);
            inspection.ObjectTypeId = from?.ObjectTypeId;
            inspection.OptTypeId = from?.OptTypeId;
            //inspection.ChildrenTypeId = from?.ChildrenTypeId;
            inspection.ModuleTypeId = from?.ModuleTypeId;

            #endregion



            //if (inspection.ParentId == null)
            //{
            //    //inspection.ParentId = (await _dbContext.DataInspection.AsQueryable().Where(x => x.TrialId == inspection.TrialId && x.SubjectVisitId == inspection.SubjectVisitId && x.SubjectId == inspection.SubjectId && x.SiteId == inspection.SiteId &&  x.GeneralId == inspection.GeneralId).OrderByDescending(x => x.CreateTime).FirstOrDefaultAsync())?.Id;


            //    inspection.ParentId = (await _dbContext.DataInspection.AsQueryable().Where(x => x.GeneralId == inspection.GeneralId && x.ObjectRelationParentId == inspection.ObjectRelationParentId).OrderByDescending(x => x.CreateTime).FirstOrDefaultAsync())?.Id;
            //}

            inspection.CreateUserName = _userInfo.UserName;
            inspection.CreateUserRealName = _userInfo.RealName;
            inspection.RoleName = _userInfo.UserTypeShortName;
            inspection.CreateUserId = _userInfo.Id;
            inspection.IP = _userInfo.IP;
            inspection.CreateTime = inspection.CreateTime == default(DateTime) ? DateTime.Now : inspection.CreateTime;

            if (_userInfo.SignId != null)
            {
                inspection.SignId = _userInfo.SignId;
                inspection.IsSign = true;
            }

            var entityName = entityObj.GetType().Name;

            inspection.JsonDetail = new InspectionJsonDetail
            {
                //稽查实体，加上扩充的信息               
                //Data = AddJsonItem(entityObj, otherItem),

                //通用信息 每条稽查必须记录的
                //CommonData = generalData

                EntityName = entityName,

                //Data 仅仅记录稽查实体的信息  CommonData  存放关联数据的信息(特殊情况下会单独赋值)
                //后期通过关联   就不需要把 OtherItem  并入到Data中
                Data = AddJsonItem(entityObj, otherItem),

                //准确来讲  此处称之为 RelationData 更贴合  为了兼容之前的数据
                CommonData = new { SiteCode = generalData.SiteCode, SubjectCode = generalData.SubjectCode },

            }.ToJsonStr();

            inspection.BatchId = _userInfo.BatchId.Value;

            inspection.EntityName = entityName;

            await _dbContext.DataInspection.AddAsync(inspection);


            //await AddInspectionRecordAsync( entityObj, inspection, otherItem);
        }


        /// <summary>
        /// 将数据库实体属性，映射到稽查实体属性 避免重复赋值
        /// </summary>
        /// <param name="date"></param>
        /// <param name="auditEntity"></param>
        public void MapEntityPropertyToAuditEntity(object data, DataInspection auditEntity)
        {
            foreach (var auditEntityPropertyInfo in auditEntity.GetType().GetProperties())
            {
                var excepetNameList = typeof(Entity).GetProperties().Select(t => t.Name)
                    .Concat(typeof(ISoftDelete).GetProperties().Select(t => t.Name))
                    .Concat(typeof(IAuditAdd<>).GetProperties().Select(t => t.Name))
                    .Concat(typeof(IAuditUpdate<>).GetProperties().Select(t => t.Name));

                var filterProperties = data.GetType().GetProperties().Where(t => !excepetNameList.Any(u => u == t.Name));

                if (filterProperties.Any(t => t.Name == auditEntityPropertyInfo.Name))
                {
                    var value = data.GetType().GetProperty(auditEntityPropertyInfo.Name).GetValue(data);

                    auditEntity.GetType().GetProperty(auditEntityPropertyInfo.Name).SetValue(auditEntity, value);
                }
            }
        }


        /// <summary>
        /// 获取稽查通用Guid数据 (每条稽查记录必须查询的)
        /// </summary>
        /// <param name="inspection"></param>
        /// <returns></returns>
        public async Task<InspectionGeneralData> GetInspectionGeneralGuidAsync(InspectionConvertDTO inspection)
        {

            InspectionGeneralData generalData = new InspectionGeneralData()
            {
                SiteId = inspection.SiteId,
                SubjectId = inspection.SubjectId,
                SubjectVisitId = inspection.SubjectVisitId,
                TrialId = inspection.TrialId
            };


            if (inspection.VisitTaskId != null)
            {

                if (generalData.TrialId == null || generalData.SiteId == null || generalData.SubjectId == null)
                {
                    var info = await _dbContext.VisitTask.Where(x => x.Id == inspection.VisitTaskId).Select(x => new { SubjectCode = x.Subject.Code, TrialSiteCode = x.Subject.TrialSite.TrialSiteCode, SubjectId = x.SubjectId, x.Subject.SiteId, x.TrialId, x.SourceSubjectVisitId, ReadModuleSubjectVisitId = (Guid?)x.ReadModule.SubjectVisitId }).FirstOrDefaultAsync();


                    generalData.TrialId = info?.TrialId ?? generalData.TrialId;
                    generalData.SubjectId = info?.SubjectId ?? generalData.SubjectId;
                    generalData.SiteId = info?.SiteId ?? generalData.SiteId;
                    generalData.SubjectVisitId = info?.SourceSubjectVisitId != null ? info?.SourceSubjectVisitId : (info?.ReadModuleSubjectVisitId != null ? info?.ReadModuleSubjectVisitId : null);

                    //以后移除
                    generalData.SiteCode = info?.TrialSiteCode ?? generalData.SiteCode;
                    generalData.SubjectCode = info?.SubjectCode ?? generalData.SubjectCode;
                }

            }

            // Suject  visit  都进行了设置   不用处理

            if (inspection.SubjectVisitId != null)
            {
                if (generalData.TrialId == null || generalData.SiteId == null || generalData.SubjectId == null)
                {
                    var info = await _dbContext.SubjectVisit.Where(x => x.Id == generalData.SubjectVisitId).Select(x =>
                  new { x.SubjectId, x.SiteId, x.TrialId, SubjectCode = x.Subject.Code, TrialSiteCode = x.Subject.TrialSite.TrialSiteCode }).FirstOrDefaultAsync();


                    generalData.TrialId = info?.TrialId ?? generalData.TrialId;
                    generalData.SiteId = info?.SiteId ?? generalData.SiteId;
                    generalData.SubjectId = info?.SubjectId ?? generalData.SubjectId;

                    //以后移除
                    generalData.SiteCode = info?.TrialSiteCode ?? generalData.SiteCode;
                    generalData.SubjectCode = info?.SubjectCode ?? generalData.SubjectCode;
                }


            }


            if (generalData.SubjectId != null)
            {
                if (generalData.TrialId == null || generalData.SiteId == null)
                {
                    var info = await _dbContext.Subject.Where(x => x.Id == generalData.SubjectId).Select(x => new { SubjectId = x.Id, x.SiteId, x.TrialId, SubjectCode = x.Code, TrialSiteCode = x.TrialSite.TrialSiteCode }).FirstOrDefaultAsync();

                    generalData.TrialId = info?.TrialId ?? generalData.TrialId;
                    generalData.SiteId = info?.SiteId ?? generalData.SiteId;

                    //以后移除
                    generalData.SiteCode = info?.TrialSiteCode ?? generalData.SiteCode;
                    generalData.SubjectCode = info?.SubjectCode ?? generalData.SubjectCode;
                }


            }

            return generalData;
        }








        /// <summary>
        /// 获取稽查记录的标识符   部分业务会进行特殊处理
        /// </summary>
        /// <returns></returns>
        public async Task<string> GetInspectionRecordIdentificationAsync<T>(InspectionConvertDTO inspection, T entityObj, string type, bool IsDistinctionInterface = true)
        {
            var entityTypeName = entityObj.GetType().Name;

            #region 标识符特殊处理

            //文档签署这块，不区分系统和项目的 需要处理为同一个标识
            if (typeof(T) == typeof(TrialDocUserTypeConfirmedUser) || typeof(T) == typeof(SystemDocConfirmedUser))
            {
                entityTypeName = "New/" + "UserSigned";
            }

            switch (entityObj.GetType().Name)
            {


                case nameof(SystemBasicData):
                    var basicData = entityObj as SystemBasicData;
                    type = type + (basicData.ParentId == null ? "/parent" : string.Empty);
                    break;

                case nameof(Trial):
                    var trial = entityObj as Trial;
                    Guid id = trial.Id;
                    var oldentity = await _dbContext.Trial.Where(x => x.Id == id).Select(t => new { t.IsTrialBasicLogicConfirmed, t.IsTrialProcessConfirmed, t.IsTrialUrgentConfirmed }).FirstOrDefaultAsync();
                    switch (_userInfo.RequestUrl.ToLower())
                    {
                        case "configtrialbasicinfo/configtrialbasicinfoconfirm":
                            type = type + "/" + oldentity.IsTrialBasicLogicConfirmed.ToString();
                            break;
                        //case "configtrialbasicinfo/configtrialprocessinfoconfirm":
                        //    type = type + "/" + oldentity.IsTrialProcessConfirmed.ToString();
                        //    break;
                        case "configtrialbasicinfo/configtrialurgentinfoconfirm":
                            type = type + "/" + oldentity.IsTrialUrgentConfirmed.ToString();
                            break;
                    }
                    break;

                case nameof(ReadingQuestionTrial):

                    var trialReadingQuestion = entityObj as ReadingQuestionTrial;

                    switch (_userInfo.RequestUrl)
                    {
                        case "ReadingImageTask/setTrialCriterionJudgeQuestionAnswerGroup":

                            if (trialReadingQuestion.JudgeType == JudgeTypeEnum.None)
                            {
                                type = type + "/" + "Reset";
                            }

                            break;
                    }
                    break;

                #region 访视相关

                //  对话消息区分用户类型
                case nameof(CheckChallengeDialog):
                    type = type + "/(" + _userInfo.UserTypeShortName + ")";

                    var checkDialog = entityObj as CheckChallengeDialog;

                    switch (_userInfo.RequestUrl.ToLower())
                    {
                        case "qcoperation/closecheckchallenge":

                            inspection.Reason = checkDialog.TalkContent.Substring(checkDialog.TalkContent.LastIndexOf(':') + 1);
                            break;
                    }

                    break;

                //  对话消息区分用户类型
                case nameof(QCChallengeDialog):
                    type = type + "/(" + _userInfo.UserTypeShortName + ")";

                    var dialog = entityObj as QCChallengeDialog;
                    switch (_userInfo.RequestUrl.ToLower())
                    {
                        case "qcoperation/closeqcchallenge":

                            inspection.Reason = dialog.TalkContent.Substring(dialog.TalkContent.LastIndexOf(':') + 1);
                            break;
                    }

                    break;


                case nameof(SubjectVisit):
                    var sv = entityObj as SubjectVisit;
                    switch (_userInfo.RequestUrl.ToLower())
                    {
                        //待处理？
                        case "qcoperation/qcpassedorfailed":

                            type = type + "/" + (40 % (int)sv.AuditState).ToString();

                            break;

                        //设置核查通过
                        case "qcoperation/setcheckpass":

                            inspection.Reason = sv.ManualPassReason;
                            break;

                        //领取或者取消QC任务
                        case "qcoperation/obtainorcancelqctask":
                            type = type + "/" + sv.IsTake.ToString();
                            break;

                        //确认重阅  区分用户类型
                        case "visittask/confirmrereading":

                            if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM)
                            {
                                type = type + "/" + 1;

                            }
                            else
                            {
                                //SPM
                                type = type + "/" + 2;
                            }
                            break;
                    }

                    if (sv.CheckChallengeState == CheckChanllengeTypeEnum.CRCWaitPMReply || sv.CheckChallengeState == CheckChanllengeTypeEnum.PMWaitCRCReply)
                    {
                        //发送对话  修改质疑状态  不需要区分接口
                        IsDistinctionInterface = false;

                        type = type + "/ModifyCheckChallengeState";
                    }
                    break;

                case nameof(NoneDicomStudy):
                    switch (_userInfo.RequestUrl.ToLower())
                    {
                        case "nonedicomstudy/addorupdatenonedicomstudy":
                            type = type + "/(" + _userInfo.UserTypeShortName + ")";
                            break;
                    }
                    break;
                #endregion


                #region 阅片任务相关

                //任务表
                case nameof(VisitTask):

                    var visitTask = entityObj as VisitTask;


                    if (type == AuditOpt.Add)
                    {
                        //生成一致性分析任务
                        if (visitTask.IsSelfAnalysis == true)
                        {
                            type = type + "/" + "SelfAnalysis";
                        }
                        else if (visitTask.IsSelfAnalysis == false)
                        {
                            type = type + "/" + "GroupAnalysis";
                        }
                        else
                        {
                            type = type + "/" + "NotAnalysis";
                        }

                        //区分任务类型
                        type = type + "/" + (int)visitTask.ReadingCategory;


                    }
                    else
                    {
                        switch (_userInfo.RequestUrl)
                        {
                            //申请重阅
                            case "VisitTask/applyReReading":
                                type = type + "/" + (int)visitTask.ReReadingApplyState;
                                break;


                            //同意重阅
                            case "VisitTask/ConfirmReReading":

                                if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM)
                                {
                                    type = type + "/" + 1;

                                }
                                else
                                {
                                    type = type + "/" + 2;
                                }

                                break;
                        }

                    }



                    break;

                //重阅记录表
                case nameof(VisitTaskReReading):

                    var visitTaskReReading = entityObj as VisitTaskReReading;

                    switch (_userInfo.RequestUrl)
                    {
                        case "VisitTask/applyReReading":
                            type = type + "/" + (int)visitTaskReReading.RequestReReadingType;
                            break;

                        case "VisitTask/ConfirmReReading":

                            if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ProjectManager || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.APM)
                            {
                                type = type + "/" + 1;

                            }
                            else
                            {
                                type = type + "/" + 2;
                            }

                            if (visitTaskReReading.RequestReReadingResultEnum == RequestReReadingResult.Agree)
                            {
                                type = type + "/" + 1;

                            }
                            else if (visitTaskReReading.RequestReReadingResultEnum == RequestReReadingResult.Reject)
                            {
                                type = type + "/" + 2;
                            }
                            break;
                    }

                    break;

                //一致性分析规则
                case nameof(TaskConsistentRule):

                    var taskConsistentRule = entityObj as TaskConsistentRule;

                    //自身一致性分析
                    if (taskConsistentRule.IsSelfAnalysis == true)
                    {
                        type = type + "/" + 1;

                    }
                    //组件一致性分析
                    else
                    {
                        type = type + "/" + 2;
                    }

                    break;
                    #endregion



            }

            #endregion

            if (IsDistinctionInterface)
            {
                return $"{_userInfo.RequestUrl}/{entityTypeName}/{type}";

            }
            else
            {
                return $"{entityTypeName}/{type}";
            }
        }


        /// 往json里面添加属性
        /// </summary>
        /// <param name="jsonObj">json</param>
        /// <param name="otherItem">添加对象</param>
        /// <returns></returns>
        public IDictionary<string, object> AddJsonItem(object jsonObj, object otherItem = null)
        {


            var JsonData = JsonConvert.DeserializeObject<IDictionary<string, object>>((jsonObj).ToJsonStr());

            if (otherItem == null)
            {
                return JsonData;
            }
            var other = JsonConvert.DeserializeObject<IDictionary<string, object>>(otherItem.ToJsonStr());

            foreach (var item in other)
            {
                if (JsonData.ContainsKey(item.Key))
                {
                    JsonData[item.Key] = item.Value;
                }
                else
                {
                    JsonData.Add(item.Key, item.Value);
                }

            }
            return JsonData;

        }



        #region 待废弃  -by zhouhang  调整


        ///// <summary>
        ///// 传入实体对象
        ///// </summary>
        //public async Task IncomingEntitys(List<EntityEntry> entitys)
        //{
        //    // 修改
        //    await InsertAddEntitys(
        //        entitys.Where(x => x.State == EntityState.Modified &&
        //        (!typeof(ISoftDelete).IsAssignableFrom(x.Entity.GetType()) || !(bool)x.Entity.GetType().GetProperty(nameof(ISoftDelete.IsDeleted)).GetValue(x.Entity) || NodeleteTableTypes.Contains(x.Entity.GetType()))
        //    ).ToList(), AuditOpt.Update);

        //    // 新增
        //    await InsertAddEntitys(entitys.Where(x => x.State == EntityState.Added).ToList(), AuditOpt.Add);

        //    // 删除
        //    await InsertAddEntitys(entitys.Where(x => x.State == EntityState.Deleted
        //    || (typeof(ISoftDelete).IsAssignableFrom(x.Entity.GetType()) && (bool)x.Entity.GetType().GetProperty(nameof(ISoftDelete.IsDeleted)).GetValue(x.Entity) && x.State == EntityState.Modified && !NodeleteTableTypes.Contains(x.Entity.GetType()))
        //    ).ToList(), AuditOpt.Deleted);


        //}

        //// 非Dicom文件
        //if (entitys.Any(x => x.Entity.GetType() == typeof(NoneDicomStudyFile)))
        //{
        //    var noneDicomStudyfile = entitys.Where(x => x.Entity.GetType() == typeof(NoneDicomStudyFile)).Select(x => x.Entity).FirstOrDefault() as NoneDicomStudyFile;
        //    var noneDicomStudy = await _dbContext.NoneDicomStudy.Where(x => x.Id == noneDicomStudyfile.NoneDicomStudyId).FirstOrDefaultAsync();
        //    if (noneDicomStudy != null)
        //    {
        //        var filecount = await _dbContext.NoneDicomStudyFile.Where(x => x.NoneDicomStudyId == noneDicomStudyfile.NoneDicomStudyId).CountAsync();
        //        var count = entitys.Where(x => x.Entity.GetType() == typeof(NoneDicomStudyFile)).ToList().Count;
        //        if (type == "Deleted")
        //        {
        //            filecount = filecount - count;
        //        }
        //        else
        //        {
        //            filecount = filecount + count;
        //        }

        //        await InsertInspection<NoneDicomStudy>(noneDicomStudy, type, null, new
        //        {
        //            FileCount = filecount,
        //        });

        //    }
        //}

        /// <summary>
        /// 获取稽查通用数据 (每条稽查记录必须查询的)
        /// </summary>
        /// <param name="inspection"></param>
        /// <returns></returns>
        public async Task<InspectionGeneralData> GetInspectionGeneralDataAsync(InspectionConvertDTO inspection)
        {

            InspectionGeneralData generalData = new InspectionGeneralData()
            {
                SiteCode = inspection.SiteCode,
                SiteId = inspection.SiteId,
                //SiteName = inspection.SiteName,
                SubjectCode = inspection.SubjectCode,
                SubjectId = inspection.SubjectId,
                SubjectVisitId = inspection.SubjectVisitId,
                SubjectVisitName = inspection.SubjectVisitName,
                ResearchProgramNo = inspection.ResearchProgramNo,
                TrialId = inspection.TrialId,
                TrialName = inspection.TrialName
            };




            #region 访视  阅片期那里关联了访视  

            //if (generalData.SubjectVisitId != null)
            //{
            //    //添加访视的时候，会带信息过来
            //    if (string.IsNullOrEmpty(generalData.SubjectVisitName))
            //    {
            //        var info = (await _dbContext.SubjectVisit.Where(x => x.Id == generalData.SubjectVisitId).Select(x =>
            //        new { x.VisitName, x.SubjectId, x.SiteId, SubjectCode = x.Subject.Code, TrialSiteCode = x.TrialSite.TrialSiteCode, x.TrialId, x.Trial.ExperimentName, x.Trial.ResearchProgramNo }).FirstOrDefaultAsync()).IfNullThrowException();

            //        generalData.SubjectVisitName = info.VisitName;

            //        generalData.TrialId = info.TrialId;
            //        generalData.TrialName = info.ExperimentName;
            //        generalData.ResearchProgramNo = info.ResearchProgramNo;
            //        generalData.SiteId = info.SiteId;
            //        generalData.SubjectCode = info.SubjectCode;
            //        generalData.SubjectId = info.SubjectId;
            //        generalData.SiteCode = info.TrialSiteCode;
            //    }
            //}


            #endregion


            #region 受试者

            if (generalData.SubjectId != null)
            {

                // 添加Subject 哪里会带信息过来
                if (string.IsNullOrEmpty(generalData.SubjectCode))
                {
                    var info = (await _dbContext.Subject.Where(x => x.Id == generalData.SubjectId).Select(x => new { SubjectId = x.Id, SubjectCode = x.Code, x.SiteId, TrialSiteCode = x.TrialSite.TrialSiteCode, x.TrialId, x.Trial.ExperimentName, x.Trial.ResearchProgramNo }).FirstOrDefaultAsync()).IfNullThrowException();


                    generalData.TrialId = info.TrialId;
                    generalData.TrialName = info.ExperimentName;
                    generalData.ResearchProgramNo = info.ResearchProgramNo;
                    generalData.SiteId = info.SiteId;
                    generalData.SubjectCode = info.SubjectCode;
                    generalData.SubjectId = info.SubjectId;
                    generalData.SiteCode = info.TrialSiteCode;

                }
            }

            #endregion



            #region 中心Code

            if (generalData.TrialId != null && generalData.SiteId != null)
            {

                generalData.SiteCode = (await _dbContext.TrialSite.IgnoreQueryFilters().Where(x => x.TrialId == generalData.TrialId && x.SiteId == generalData.SiteId).Select(t => t.TrialSiteCode).FirstOrDefaultAsync()).IfNullThrowException();


            }


            #endregion


            #region 项目名称


            if (generalData.TrialId != null)
            {

                //项目添加哪里 直接会带信息过来，不用查询数据库  其他的地方需要查询数据库
                if (string.IsNullOrEmpty(generalData.ResearchProgramNo) || string.IsNullOrEmpty(generalData.TrialName))
                {
                    var trialdata = (await _dbContext.Trial.Select(x => new { x.Id, x.ResearchProgramNo, x.ExperimentName, }).FirstOrDefaultAsync(x => x.Id == generalData.TrialId)).IfNullThrowException();

                    generalData.ResearchProgramNo = trialdata.ResearchProgramNo;

                    generalData.TrialName = trialdata.ExperimentName;
                }
            }

            #endregion



            return generalData;
        }





        ///// <summary>
        ///// 映射数据
        ///// </summary>
        ///// <param name="data"></param>
        ///// <param name="mapData">要赋值的对象</param>
        //public void MapData(dynamic data, dynamic mapData)
        //{
        //    List<string> column = new List<string>() { "TrialId", "SiteId", "SubjectId", "SubjectVisitId", "CreateUserName", "TrialName", "SiteName", "SubjectCode", "VisitName", "SubjectVisitName", "RoleName", "SiteCode", "ResearchProgramNo" };
        //    foreach (var item in column)
        //    {
        //        try
        //        {
        //            var i = mapData.GetType().GetProperty(item).GetValue(mapData);
        //            if (i == null || i == default(Guid))
        //            {
        //                var value = data.GetType().GetProperty(item).GetValue(data);
        //                mapData.GetType().GetProperty(item).SetValue(mapData, value);
        //            }

        //        }
        //        catch (Exception)
        //        {
        //            continue;

        //        }
        //    }
        //}

        ///// <summary>
        ///// 添加稽查
        ///// </summary>
        ///// <param name="add">新增的稽查对象</param>
        ///// <param name="data">数据</param>
        ///// <returns></returns>
        ///// <exception cref="BusinessValidationFailedException"></exception>
        //public async Task AddInspectionRecordAsync<T>(T data, InspectionConvertDTO add, object otherItem = null) where T : class
        //{
        //    //MapData(data, add);

        //    MapEntityPropertyToAuditEntity(data, add);

        //    InspectionGeneralData generalData = new InspectionGeneralData()
        //    {
        //        //CreateUserName = add.CreateUserName,
        //        SiteCode = add.SiteCode,
        //        SiteId = add.SiteId,
        //        //SiteName = add.SiteName,
        //        SubjectCode = add.SubjectCode,
        //        SubjectId = add.SubjectId,
        //        SubjectVisitId = add.SubjectVisitId,
        //        SubjectVisitName = add.SubjectVisitName,
        //        ResearchProgramNo = add.ResearchProgramNo,
        //        //RoleName = add.RoleName,
        //        TrialId = add.TrialId,
        //        TrialName = add.TrialName
        //    };

        //    await SetInspectionNameValue(generalData);

        //    #region 处理标识

        //    var from = await _dbContext.FrontAuditConfig.FirstOrDefaultAsync(x => x.Identification == add.Identification);
        //    add.ObjectTypeId = from?.ObjectTypeId;
        //    add.OptTypeId = from?.OptTypeId;
        //    add.ChildrenTypeId = from?.ChildrenTypeId;
        //    add.ModuleTypeId = from?.ModuleTypeId;

        //    #endregion
        //    if (add.ParentId == null)
        //    {
        //        add.ParentId = (await _dbContext.DataInspection.AsQueryable().Where(x => x.TrialId == add.TrialId && x.SubjectVisitId == add.SubjectVisitId && x.SubjectId == add.SubjectId && x.SiteId == add.SiteId && x.VisitStageId == add.VisitStageId && x.GeneralId == add.GeneralId).OrderByDescending(x => x.CreateTime).FirstOrDefaultAsync())?.Id;
        //    }
        //    add.CreateUserId = _userInfo.Id;
        //    add.IP = _userInfo.IP;
        //    add.CreateTime = add.CreateTime == default(DateTime) ? DateTime.Now : add.CreateTime;

        //    if (_userInfo.SignId != null)
        //    {
        //        add.SignId = _userInfo.SignId;
        //        add.IsSign = true;
        //    }

        //    var inspectionData = new InspectionJsonDetail()
        //    {
        //        //稽查实体，加上扩充的信息
        //        Data = AddJsonItem(data, otherItem),

        //        //通用信息
        //        CommonData = generalData
        //    };
        //    add.JsonDetail = inspectionData.ToJsonStr();
        //    add.BatchId = _userInfo.BatchId.Value;
        //    await _dbContext.DataInspection.AddAsync(add);
        //}


        ///// <summary>
        ///// 设置项目以及名称
        ///// </summary>
        ///// <param name="generalData"></param>
        ///// <returns></returns>
        //public async Task SetInspectionNameValue(InspectionGeneralData generalData)
        //{
        //    #region 项目名称


        //    if (generalData.TrialId != null)
        //    {

        //        //项目添加哪里 直接会带信息过来，不用查询数据库  其他的地方需要查询数据库
        //        if (string.IsNullOrEmpty(generalData.ResearchProgramNo) || string.IsNullOrEmpty(generalData.TrialName))
        //        {
        //            var trialdata = (await _dbContext.Trial.Select(x => new { x.Id, x.ResearchProgramNo, x.ExperimentName, }).FirstOrDefaultAsync(x => x.Id == generalData.TrialId)).IfNullThrowException();

        //            generalData.ResearchProgramNo = trialdata.ResearchProgramNo;

        //            generalData.TrialName = trialdata.ExperimentName;
        //        }
        //    }

        //    #endregion

        //    #region 测试中心名称

        //    if (generalData.TrialId != null && generalData.SiteId != null)
        //    {

        //        generalData.SiteCode = (await _dbContext.TrialSite.IgnoreQueryFilters().Where(x => x.TrialId == generalData.TrialId && x.SiteId == generalData.SiteId).Select(t => t.TrialSiteCode).FirstOrDefaultAsync()).IfNullThrowException();


        //        //// 添加Site 哪里会带信息过来
        //        //if (string.IsNullOrEmpty(generalData.SiteName))
        //        //{
        //        //    generalData.SiteName = (await _dbContext.Site.Where(x => x.Id == generalData.SiteId).Select(x => x.SiteName).FirstOrDefaultAsync()).IfNullThrowException();

        //        //}
        //    }


        //    #endregion

        //    #region 受试者

        //    if (generalData.SubjectId != null)
        //    {

        //        // 添加Subject 哪里会带信息过来
        //        if (string.IsNullOrEmpty(generalData.SubjectCode))
        //        {
        //            generalData.SubjectCode = (await _dbContext.Subject.Where(x => x.Id == generalData.SubjectId).Select(x => x.Code).FirstOrDefaultAsync()).IfNullThrowException();

        //        }
        //    }

        //    #endregion

        //    #region 访视

        //    if (generalData.SubjectVisitId != null)
        //    {
        //        //添加访视的时候，会带信息过来
        //        if (string.IsNullOrEmpty(generalData.SubjectVisitName))
        //        {
        //            generalData.SubjectVisitName = (await _dbContext.SubjectVisit.Where(x => x.Id == generalData.SubjectVisitId).Select(x => x.VisitName).FirstOrDefaultAsync()).IfNullThrowException();
        //        }
        //    }


        //    #endregion

        //}


        #endregion

    }
}
