//--------------------------------------------------------------------
//     此代码由T4模板自动生成  byzhouhang 20210918
//	   生成时间 2022-03-28 16:46:23 
//     对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------

using Microsoft.AspNetCore.Mvc;
using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.ViewModel;
using Castle.Core.Internal;
using MassTransit;
using IRaCIS.Core.Infra.EFCore.Common.Dto;
using Microsoft.Data.SqlClient;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using IRaCIS.Core.Domain.Share;

namespace IRaCIS.Core.Application.Service 
{

    /// <summary>
    /// FrontAuditConfigService
    /// </summary>	
    [ApiExplorerSettings(GroupName = "Reviewer")]
    public class FrontAuditConfigService : BaseService, IFrontAuditConfigService
    {

        private readonly IRepository<FrontAuditConfig> _frontAuditConfigRepository;
        private readonly IRepository<QCChallengeDialog> _qCChallengeDialogRepository;
        private readonly IRepository<DataInspection> _dataInspectionRepository;
        private readonly IRepository<QCChallenge> _qCChallengeRepository;
        private readonly IRepository<Dictionary> _dictionaryRepository;
        private readonly IRepository<Trial> _trialRepository;
        private readonly IRepository<CheckChallengeDialog> _checkChallengeDialogRepository;

        public FrontAuditConfigService(IRepository<FrontAuditConfig> frontAuditConfigRepository,
            IRepository<QCChallengeDialog> qCChallengeDialogRepository,
              IRepository<DataInspection> dataInspectionRepository,
            IRepository<QCChallenge> qCChallengeRepository,
             IRepository<Dictionary> dictionaryRepository,
              IRepository<Trial> trialRepository,
            IRepository<CheckChallengeDialog> checkChallengeDialogRepository
            )
        {
            _frontAuditConfigRepository = frontAuditConfigRepository;
            this._qCChallengeDialogRepository = qCChallengeDialogRepository;
            this._dataInspectionRepository = dataInspectionRepository;
            this._qCChallengeRepository = qCChallengeRepository;
            this._dictionaryRepository = dictionaryRepository;
            this._trialRepository = trialRepository;
            this._checkChallengeDialogRepository = checkChallengeDialogRepository;
        }

        /// <summary>
        /// 获取数据库所有表
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<TableList>> GetDatabaseTables()
        {
            return await _frontAuditConfigRepository._dbContext.GetTableList().ToListAsync();
        }

        /// <summary>
        /// 获取查询对象
        /// </summary>
        /// <param name="inDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<AccessToDialogueOutDto>> GetDialogList(AccessToDialogueInDto inDto)
        {
            List<AccessToDialogueOutDto> data = new List<AccessToDialogueOutDto>();

            switch (inDto.Type)
            {
                case AccessToDialogueEnum.Question:

                    AccessToDialogueOutDto title = (await _qCChallengeRepository.Where(x => x.Id == inDto.Id).Include(x => x.CreateUser).Select(x => new AccessToDialogueOutDto()
                    {
                        CreateTime = x.CreateTime,
                        CreateUserName = x.CreateUser.UserName,
                        TalkContent = x.Content,
                        IsTitle = true,
                    }).FirstOrDefaultAsync())?? new AccessToDialogueOutDto();

                    data =await _qCChallengeDialogRepository.Where(x => x.QCChallengeId == inDto.Id && x.CreateTime <= inDto.Createtime).Include(x => x.CreateUser).Select(
                        x => new AccessToDialogueOutDto()
                        {
                            CreateTime = x.CreateTime,
                            CreateUserName = x.CreateUser.UserName,
                            TalkContent = x.TalkContent
                        }
                        ).OrderBy(x => x.CreateTime).ToListAsync();

                    data.Insert(0, title);

                    break;
                case AccessToDialogueEnum.Consistency:
                    data = await _checkChallengeDialogRepository.Where(x => x.SubjectVisitId == inDto.Id && x.CreateTime <= inDto.Createtime).Include(x => x.CreateUser).Select(
                        x => new AccessToDialogueOutDto()
                        {
                            CreateTime = x.CreateTime,
                            CreateUserName = x.CreateUser.UserName,
                            TalkContent = x.TalkContent
                        }
                        ).OrderBy(x => x.CreateTime).ToListAsync();
                    break;

            }

            return data;
        }

        /// <summary>
        /// 获取表列名
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<TableList>> GetTableColumn(string tableName)
        {
            return await _frontAuditConfigRepository._dbContext.GetTableColumn(tableName).ToListAsync();
        }

        /// <summary>
        /// 复制配置项及其子项
        /// </summary>
        /// <param name="input">传入对象</param>
        /// <returns></returns>
        [HttpPost]
        public async Task CopyFrontAuditConfigItem(CopyFrontAuditConfigItemDto input)
        {
            var id = NewId.NextGuid();
            List<FrontAuditConfig> frontAudits= new List<FrontAuditConfig>();

            var frontAuditConfig = (await _frontAuditConfigRepository.FirstOrDefaultAsync(x => x.Id == input.ChildId)).Clone();
            var fronts = await _frontAuditConfigRepository.Where(x => x.ParentId == frontAuditConfig.Id).ToListAsync();
            fronts.ForEach(x =>
            {
                x.Id = NewId.NextGuid();
                x.ParentId = id;
            });
            frontAuditConfig.ParentId = input.ParentId;
            frontAuditConfig.Id = id;
            frontAudits.Add(frontAuditConfig);
            frontAudits.AddRange(fronts);

            await _frontAuditConfigRepository.AddRangeAsync(frontAudits);
            await _frontAuditConfigRepository.SaveChangesAsync();

        }

        /// <summary>
        /// 批量添加字段
        /// </summary>
        /// <param name="data">数据集</param>
        /// <returns></returns>
        public async Task BatchAddFrontAudit(BatchAddFrontAudit data)
        {
            var maxSort = await _frontAuditConfigRepository.Where(x => x.ParentId == data.ParentId).MaxAsync(x => x.Sort);

            List<FrontAuditConfig>  fronts=new List<FrontAuditConfig>();
            foreach (var item in data.Columns)
            {
                maxSort++;
                fronts.Add(new FrontAuditConfig()
                {
                    Sort = maxSort,
                    Code = item.Name,
                    ValueCN = item.Remake,
                    IsEnable = true,
                    ParentId = data.ParentId
                });
            }

            await _frontAuditConfigRepository.AddRangeAsync(fronts);
        }

        /// <summary>
        /// 翻译稽查数据
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<string>> SetInspectionEnumValue(SetInspectionEnumValueDto dto)
        {
            return await SetInspectionEnumValueDataList(dto);
        }



        /// <summary>
        /// 翻译稽查数据
        /// </summary>
        /// <param name="dto">传入Dto</param>
        /// <returns></returns>
        private async Task<List<string>> SetInspectionEnumValueDataList(SetInspectionEnumValueDto dto)
        {
            var auditDatas =await _dataInspectionRepository.AsQueryable().Where(x => dto.AuditDataIds.Contains(x.Id)).Select(x=> new SetInspectionEnumDataDto() { 
            Id=x.Id,
            JsonStr=x.JsonDetail,
            Identification=x.Identification
            }).ToListAsync();




            var listIdentification = auditDatas.Select(x => x.Identification).ToList();
            foreach (var item in auditDatas)
            {
                Dictionary<string, object> jsonDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(item.JsonStr);

              
                item.JsonStr = jsonDict["Data"].ToString();
                if (item.Identification == string.Empty || item.JsonStr == string.Empty)
                {
                    continue;
                }
                item.JsonStr = await GetInspectionEnumValue(listIdentification, item.JsonStr);
                item.JsonStr = await SetEnum(dto.TrialId, listIdentification, item.JsonStr);
                item.JsonStr = await SetDataInspectionDateType(listIdentification, item.JsonStr);
                jsonDict["Data"] = JsonConvert.DeserializeObject<object>(item.JsonStr) ;

                item.JsonStr = JsonConvert.SerializeObject(jsonDict);
            }

            var resultJsonStrList = new List<string>();

            dto.AuditDataIds.ForEach(x =>
            {
                var auditData = auditDatas.FirstOrDefault(y => y.Id == x);
                resultJsonStrList.Add(auditData?.JsonStr);
            });

            if (resultJsonStrList.Count() < 2)
            {
                resultJsonStrList.Add(String.Empty);
            }
            return resultJsonStrList;
        }





        /// <summary>
        /// 格式化日期和时间
        /// </summary>
        /// <param name="identificationList"></param>
        /// <param name="jsonStr"></param>
        /// <returns></returns>
        private async Task<string> SetDataInspectionDateType(List<string> identificationList, string jsonStr)
        {
            var list = await (from parent in _frontAuditConfigRepository.AsQueryable().Where(x => identificationList.Contains(x.Identification))
                              join child in _frontAuditConfigRepository.AsQueryable().Where(x => x.EnumType == "Date" && x.IsEnable ) on parent.Id equals child.ParentId
                              select new DateDto()
                              {
                                  Code = child.Code,
                                  DateType = child.DateType,
                              }).ToListAsync();

            list = list.GroupBy(x => new { x.Code }, (key, lst) => new DateDto()
            {
                Code = key.Code,
                DateType = lst.Max(x => x.DateType),
            }).ToList();

            var jsonDataDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(jsonStr);

            if (jsonDataDic == null)
            {
                return jsonStr;
            }

            foreach (var item in jsonDataDic.Keys)
            {
                var datefirst = list.FirstOrDefault(x => x.Code.ToLower() == item.ToLower());
                if (datefirst != null && !IsNullOrEmpty(jsonDataDic[item]))
                {
                    try
                    {
                        if (datefirst.DateType == "Date")
                        {
                            jsonDataDic[item] = DateTime.Parse(jsonDataDic[item].ToString()).ToString("yyyy-MM-dd");
                        }

                        if (datefirst.DateType == "DateTime")
                        {
                            jsonDataDic[item] = DateTime.Parse(jsonDataDic[item].ToString()).ToString("yyyy-MM-dd HH:mm:ss");
                        }
                    }
                    catch (Exception)
                    {
                        continue;
                    }
                }

            }

            return JsonConvert.SerializeObject(jsonDataDic);


        }

        /// <summary>
        /// 获取外键表数据
        /// </summary>
        /// <param name="identificationList"></param>
        /// <param name="jsonStr"></param>
        /// <returns></returns>
        ///// <param name="Table">表名称</param>
        ///// <param name="ForeignKeyValue">外键value</param>
        ///// <param name="ForeignKeyText">要查询的外键值</param>
        ///// <param name="value">传入的纸</param>
        private async Task<string> GetInspectionEnumValue(List<string> identificationList, string jsonStr)
        {
            var list = await (from u in _frontAuditConfigRepository.Where(x => identificationList.Contains(x.Identification))
                              join p in _frontAuditConfigRepository.Where(x => x.EnumType == "Foreign" && x.IsEnable) on u.Id equals p.ParentId
                              select new
                              {
                                  Key = p.Code,
                                  ForeignKeyValue = p.ForeignKeyValue,
                                  ForeignKeyText = p.ForeignKeyText,
                                  ForeignKeyTable = p.ForeignKeyTableName
                              }).ToListAsync();
            list = list.GroupBy(x => new { x.Key }, (key, lst) => new
            {
                Key = key.Key,
                ForeignKeyValue = lst.Max(x => x.ForeignKeyValue),
                ForeignKeyText = lst.Max(x => x.ForeignKeyText),
                ForeignKeyTable = lst.Max(x => x.ForeignKeyTable),

            }).ToList();

            var jsonDataValueDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(jsonStr);
            foreach (var item in list)
            {
                if (!jsonDataValueDic.ContainsKey(item.Key))
                {
                    continue;
                }
                string Table = item.ForeignKeyTable;
                string ForeignKeyValue = item.ForeignKeyValue;
                string ForeignKeyText = item.ForeignKeyText;
                if (jsonDataValueDic[item.Key] != null)
                {
                    string value = jsonDataValueDic[item.Key].ToString();
                    string para = string.Empty;
                    string sql = string.Empty;
                    var JsonData = JsonConvert.DeserializeObject<IDictionary<string, object>>(JsonConvert.SerializeObject(new { item = value }));
                    if (JsonData["item"].GetType() == typeof(JArray))
                    {
                        foreach (var v in JsonData["item"] as JArray)
                        {
                            para += para == string.Empty ? $"'{v.ToString()}'" : $",'{v.ToString()}'";
                        }
                        sql = $"select {ForeignKeyText} Text from {Table} where {ForeignKeyValue} in (@para)";
                    }
                    else
                    {
                        para = $"{JsonData["item"].ToString()}";
                        sql = $"select {ForeignKeyText}  Text from {Table} where {ForeignKeyValue} = @para";
                    }
                    SqlParameter[] paravalue = new SqlParameter[] {
                   new SqlParameter("@para",para)
                                             };
                    jsonDataValueDic[item.Key] = string.Join(",", _frontAuditConfigRepository._dbContext.Database.SqlQuery<ForeignKey>(sql, paravalue).Select(x => x.Text).ToList());
                }
            }
            return JsonConvert.SerializeObject(jsonDataValueDic);
        }


        /// <summary>
        /// 获取枚举
        /// </summary>
        /// <param name="trialId">标识</param>
        /// <param name="identificationList">标识</param>
        /// <param name="jsonStr">Json对象</param>
        /// <returns></returns>
        private async Task<string> SetEnum(Guid trialId, List<string> identificationList, string jsonStr)
        {
            if (jsonStr == null || jsonStr == "null")
            {
                return null;
            }
            var list = await (from u in _frontAuditConfigRepository.Where(x => identificationList.Contains(x.Identification))
                              join p in _frontAuditConfigRepository.Where(x => x.Code != "AuditState" && x.EnumType == "Dictionary" && x.IsEnable) on u.Id equals p.ParentId
                              select new
                              {
                                  Key = p.Code,
                                  Code = p.DictionaryCode,
                                  Type = p.DictionaryType
                              }).ToListAsync();

            // 添加单双审
            var trialtype = await _trialRepository.AsQueryable().Where(x => x.Id == trialId).Select(x => x.QCProcessEnum).FirstOrDefaultAsync();

            list.Add(new
            {

                Key = "AuditState",
                Code = trialtype == TrialQCProcess.SingleAudit ? "AuditStatePE" : "AuditStateRC",
                Type = "Code",
            });


            list = list.GroupBy(x => new { x.Key }, (key, lst) => new
            {
                Key = key.Key,
                Code = lst.Max(x => x.Code),
                Type = lst.Max(x => x.Type),
            }).ToList();

            var jsonDataDic = JsonConvert.DeserializeObject<IDictionary<string, object>>(jsonStr);
            foreach (var item in list)
            {
                try
                {

                    if (!jsonDataDic.ContainsKey(item.Key) || jsonDataDic[item.Key] == null)
                    {
                        continue;
                    }
                    var value = jsonDataDic[item.Key];
                    if (value.GetType() == typeof(JArray))
                    {
                        JArray arrays = (JArray)value;
                        if (item.Type.ToLower() == "id".ToLower())
                        {
                            List<Guid> guids = new List<Guid>();
                            arrays.ForEach(x =>
                            {
                                guids.Add(Guid.Parse(x.ToString()));
                            });
                            jsonDataDic[item.Key] = string.Join(',', await _dictionaryRepository.Where(x => guids.Contains(x.Id)).Select(x => x.ValueCN).ToListAsync());
                        }
                        else if (item.Type.ToLower() == "ChildGroup".ToLower())
                        {
                            List<string> guids = new List<string>();
                            arrays.ForEach(x =>
                            {
                                guids.Add(x.ToString());
                            });
                            jsonDataDic[item.Key] = string.Join(',', await
                               _dictionaryRepository.Where(x => x.Code == item.Code).GroupJoin(
                                    _dictionaryRepository.Where(x => guids.Contains(x.ChildGroup)), a => a.Id, b => b.ParentId, (a, b) => new
                                    {
                                        parent = b
                                    }).SelectMany(a => a.parent, (m, n) => new
                                    {
                                        value = n.ValueCN
                                    }).Select(x => x.value).ToListAsync()
                                    );
                        }
                        else
                        {
                            List<string> guids = new List<string>();
                            arrays.ForEach(x =>
                            {
                                guids.Add(x.ToString());
                            });
                            jsonDataDic[item.Key] = string.Join(',', await
                                _dictionaryRepository.Where(x => x.Code == item.Code).GroupJoin(
                                     _dictionaryRepository.Where(x => guids.Contains(x.Code)), a => a.Id, b => b.ParentId, (a, b) => new
                                     {
                                         parent = b
                                     }).SelectMany(a => a.parent, (m, n) => new
                                     {
                                         value = n.ValueCN
                                     }).Select(x => x.value).ToListAsync()
                                    );
                        }
                    }
                    else
                    {
                        if (item.Type.ToLower() == "id".ToLower())
                        {
                            Guid guid = Guid.Parse(value.ToString());
                            jsonDataDic[item.Key] = await _dictionaryRepository.Where(x => guid == x.Id).Select(x => x.ValueCN).FirstOrDefaultAsync();
                        }
                        else if (item.Type.ToLower() == "ChildGroup".ToLower())
                        {
                            jsonDataDic[item.Key] = await _dictionaryRepository.Where(x => x.Code == item.Code).Join(_dictionaryRepository.Where(x => x.ChildGroup == value.ToString()), a => a.Id, b => b.ParentId, (a, b) => new
                            {
                                value = b.ValueCN
                            }).Select(x => x.value).FirstOrDefaultAsync();
                        }
                        else
                        {
                            jsonDataDic[item.Key] = await _dictionaryRepository.Where(x => x.Code == item.Code).Join(_dictionaryRepository.Where(x => x.Code == value.ToString()), a => a.Id, b => b.ParentId, (a, b) => new
                            {
                                value = b.ValueCN
                            }).Select(x => x.value).FirstOrDefaultAsync();
                        }
                    }
                }
                catch (Exception)
                {
                }
            }
            return JsonConvert.SerializeObject(jsonDataDic);
        }




        /// <summary>
        /// 格式化日期和时间
        /// </summary>
        /// <param name="Data">稽查数据</param>
        /// <returns></returns>
        private async Task<DataInspection> SetDataInspectionDateType(DataInspection Data)
        {
            var list = await (from parent in _frontAuditConfigRepository.AsQueryable().Where(x => x.Identification == Data.Identification)
                              join child in _frontAuditConfigRepository.AsQueryable().Where(x => x.EnumType == "Date") on parent.Id equals child.ParentId
                              select new DateDto()
                              {
                                  Code = child.Code,
                                  DateType = child.DateType,
                              }).ToListAsync();

            var JsonData = JsonConvert.DeserializeObject<IDictionary<string, object>>(Data.JsonDetail);

            foreach (var item in JsonData.Keys)
            {
                var datefirst = list.FirstOrDefault(x => x.Code.ToLower() == item.ToLower());
                if (datefirst != null && !IsNullOrEmpty(JsonData[item]))
                {
                    try
                    {
                        if (datefirst.DateType == "Date")
                        {
                            JsonData[item] = DateTime.Parse(JsonData[item].ToString()).ToString("yyyy-MM-dd");
                        }

                        if (datefirst.DateType == "DateTime")
                        {
                            JsonData[item] = DateTime.Parse(JsonData[item].ToString()).ToString("yyyy-MM-dd HH:mm:ss");
                        }
                    }
                    catch (Exception)
                    {
                        continue;
                    }
                }

            }
            Data.JsonDetail = JsonConvert.SerializeObject(JsonData);

            return Data;
        }

        /// <summary>
        /// IsNullOrEmpty
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private bool IsNullOrEmpty(object value)
        {
            if (value == null || value.ToString() == string.Empty)
            {
                return true;
            }
            else
            {
                return false;
            }
        }



        /// <summary>
        /// 获取子数据
        /// </summary>
        /// <param name="frontAuditConfigId"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<List<FrontAuditConfig>> GetAuditConfigChildList(Guid frontAuditConfigId)
        {
            var list =await (from data in _repository.GetQueryable<FrontAuditConfig>().Where(x => x.Id == frontAuditConfigId)
                       join childrenType in _repository.GetQueryable<FrontAuditConfig>() on data.Id equals childrenType.ParentId 
                       select childrenType).OrderBy(x=>x.Sort).ToListAsync();
            return list;
        }

        /// <summary>
        /// 完全复制其他子项到当前项
        /// </summary>
        /// <param name="fully"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> FullyReplicated(FullyReplicated fully)
        {
            await _frontAuditConfigRepository.DeleteFromQueryAsync(x => x.ParentId == fully.ToItemId);
            var list = await _frontAuditConfigRepository.Where(x => x.ParentId == fully.FromItemId).ToListAsync();
            list.ForEach(x =>
            {
                x.Id = NewId.NextGuid();
                x.ParentId = fully.ToItemId;
            });
            await _frontAuditConfigRepository.AddRangeAsync(list);
            await _frontAuditConfigRepository.SaveChangesAsync();
            return ResponseOutput.Ok();
        }


        /// <summary>
        /// Cope子项数据
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IResponseOutput> CopyOtherToThisItem(CopyOtherToThisItem item)
        {

            var lists = _frontAuditConfigRepository.Where(x => x.ParentId == item.AddItemGuid).ToList();

            var additem = await _frontAuditConfigRepository.FirstOrDefaultAsync(x => x.Id == item.AddItemGuid); 

            var alllist = _frontAuditConfigRepository.Where(x => item.DataSourceGuids.Contains(x.ParentId)).ToList().GroupBy(x => new { x.ValueCN }, (key, lst) => new FrontAuditConfig
            {
                Sort = lst.Select(x => x.Sort).FirstOrDefault(),
                IsShowByTrialConfig= lst.Select(x => x.IsShowByTrialConfig).FirstOrDefault(),
                TrialConfigRelyFieldName = lst.Select(x => x.TrialConfigRelyFieldName).FirstOrDefault(),
                Code = lst.Max(x => x.Code),
                ConfigType = lst.Select(x => x.ConfigType).FirstOrDefault(),
                CreateTime = DateTime.Now,
                Description = lst.Select(x => x.Description).FirstOrDefault(),
                //EnumList = lst.Select(x => x.EnumList).FirstOrDefault(),
                //IsConfig = lst.Select(x => x.IsConfig).FirstOrDefault(),
                IsShowParent = lst.Select(x => x.IsShowParent).FirstOrDefault(),
                ParentId = item.AddItemGuid,
                CreateUserId = _userInfo.Id,
                IsEnable = lst.Select(x => x.IsEnable).FirstOrDefault(),
                DictionaryKey = lst.Select(x => x.DictionaryKey).FirstOrDefault(),
                EnumType = lst.Select(x => x.EnumType).FirstOrDefault(),
                UpdateTime = DateTime.Now,
                ValueCN = lst.Select(x => x.ValueCN).FirstOrDefault(),
                Value = lst.Max(x => x.Value),
                UpdateUserId = _userInfo.Id,
                ChildrenTypeId= additem?.ChildrenTypeId,
                ModuleTypeId = additem?.ModuleTypeId,
                ObjectTypeId = additem?.ObjectTypeId,
                OptTypeId = additem?.OptTypeId,
                DictionaryCode = lst.Max(x => x.DictionaryCode),
                DictionaryType = lst.Max(x => x.DictionaryType),
                DateType = lst.Select(x => x.DateType).FirstOrDefault(),
                ForeignKeyValue = lst.Select(x => x.ForeignKeyValue).FirstOrDefault(),
                ForeignKeyText = lst.Select(x => x.ForeignKeyText).FirstOrDefault(),
                ForeignKeyTableName = lst.Select(x => x.ForeignKeyTableName).FirstOrDefault(),
                DataType = lst.Select(x => x.DataType).FirstOrDefault(),
                Id =NewId.NextGuid()//新id,
            }).ToList();

            // 获取已存在的所有名称
            var names = lists.Select(x => x.ValueCN).ToList();

            // 获取不存在的数据
            var list = alllist.Where(x => !names.Contains(x.ValueCN)).ToList();

            // 获取要添加的name
            var addvaluecns = list.Select(x => x.ValueCN);

            // 获取要修改的数据
            var neewupdate = lists.Where(x => !addvaluecns.Contains(x.ValueCN));

            neewupdate.ForEach(x =>
            {
                var item = alllist.FirstOrDefault(y => y.ValueCN == x.ValueCN);
                if (item != null)
                { 
                    x.Code=item.Code;
                    x.Value = !item.Code.IsNullOrEmpty() ? item.Value : x.Value;
                    x.DictionaryType = !item.DictionaryType.IsNullOrEmpty() ? item.DictionaryType : x.DictionaryType;
                    x.DictionaryCode = !item.DictionaryCode.IsNullOrEmpty() ? item.DictionaryCode : x.DictionaryCode;
                    x.DataType = !item.DataType.IsNullOrEmpty() ? item.DataType : x.DataType;
                    x.DateType = !item.DateType.IsNullOrEmpty() ? item.DateType : x.DateType;
                    x.DictionaryKey = !item.DictionaryKey.IsNullOrEmpty() ? item.DictionaryKey : x.DictionaryKey;
                    x.IsShowParent = !item.IsShowParent==null ? item.IsShowParent : x.IsShowParent;
                    x.ForeignKeyTableName = !item.ForeignKeyTableName.IsNullOrEmpty() ? item.ForeignKeyTableName : x.ForeignKeyTableName;
                    x.ForeignKeyText = !item.ForeignKeyText.IsNullOrEmpty() ? item.ForeignKeyText : x.ForeignKeyText;
                    x.ForeignKeyValue = !item.ForeignKeyValue.IsNullOrEmpty() ? item.ForeignKeyValue : x.ForeignKeyValue;
                    x.EnumType = !item.EnumType.IsNullOrEmpty() ? item.EnumType : x.EnumType;
                }

            });


            await  _repository.UpdateRange(neewupdate);
            await  _repository.AddRangeAsync(list);
            await _repository.SaveChangesAsync();

            return ResponseOutput.Ok();
        }


        /// <summary>
        /// 获取Description
        /// </summary>
        /// <param name="moduleTypeId"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<List<string>> GetModuleTypeDescriptionList(Guid moduleTypeId)
        {
            var result= await _frontAuditConfigRepository.Where(x=>x.ModuleTypeId== moduleTypeId && x.Description!=string.Empty).Select(x=>x.Description).Distinct().ToListAsync();
            return result;
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="iq"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<FrontAuditConfigView>> GetFrontAuditConfigList(FrontAuditConfigQuery iq)
        {
            var query = from data in _repository.GetQueryable<FrontAuditConfig>()
                     join childrenType in _repository.GetQueryable<Dictionary>() on data.ChildrenTypeId equals childrenType.Id into childrenTypetemp
                     from leftchildrenType in childrenTypetemp.DefaultIfEmpty()
                     join ModuleType in _repository.GetQueryable<Dictionary>() on data.ModuleTypeId equals ModuleType.Id into ModuleTypetemp
                     from leftModuleType in ModuleTypetemp.DefaultIfEmpty()
                     join OptTypeId in _repository.GetQueryable<Dictionary>() on data.OptTypeId equals OptTypeId.Id into OptTypeIdtemp
                     from leftOptTypeId in OptTypeIdtemp.DefaultIfEmpty()
                     join ObjectTypeId in _repository.GetQueryable<Dictionary>() on data.ObjectTypeId equals ObjectTypeId.Id into ObjectTypeIdtemp
                     from leftObjectTypeIdtemp in ObjectTypeIdtemp.DefaultIfEmpty()
                     select new FrontAuditConfigView()
                     {
                         IsShowParent = data.IsShowParent,
                         ChildrenTypeId = data.ChildrenTypeId,
                         Code = data.Code,
                         ConfigType = data.ConfigType,
                         CreateTime = data.CreateTime,
                         CreateUserId = data.CreateUserId,
                         Description = data.Description,
                         IsConfig = data.IsConfig,
                         IsEnable = data.IsEnable,
                         ModuleTypeId = data.ModuleTypeId,
                         Id = data.Id,
                         ParentId = data.ParentId,
                         UpdateTime = data.UpdateTime,
                         Value = data.Value,
                         ChildrenTypeValueCN = leftchildrenType.ValueCN,
                         ModuleTypeValue = leftModuleType.Value,
                         ModuleTypeValueCN = leftModuleType.ValueCN,
                         OptTypeId = data.OptTypeId,
                         OptTypeValue = leftOptTypeId.Value,
                         OptTypeValueCN = leftOptTypeId.ValueCN,
                         UpdateUserId = data.UpdateUserId,
                         Sort=data.Sort,
                         ValueCN = data.ValueCN,
                         ChildrenTypeValue = leftchildrenType.Value,
                       
                         DictionaryKey=data.DictionaryKey,
                         EnumType=data.EnumType,
                         ObjectTypeId=data.ObjectTypeId,
                         ObjectTypeValue = leftObjectTypeIdtemp.Value,
                         ObjectTypeValueCN = leftObjectTypeIdtemp.ValueCN,
                         IsShowByTrialConfig =data.IsShowByTrialConfig,
                         TrialConfigRelyFieldName = data.TrialConfigRelyFieldName,
                        
                         Identification=data.Identification,
                         IsHaveReason=data.IsHaveReason,
                         IsHaveSign=data.IsHaveSign,
                         IsFinish=data.IsFinish,
                         IsJoinPlan=data.IsJoinPlan,
                         DataType=data.DataType,
                         ChildDataLabel=data.ChildDataLabel,
                         ChildDataValue=data.ChildDataValue,
                         IsSpecialType=data.IsSpecialType,
                         DateType=data.DataType,
                         DictionaryCode=data.DictionaryCode,
                         DictionaryType=data.DictionaryType,
                         InterfaceName=data.InterfaceName,
                     };

            query = query
                .WhereIf(!iq.Value.IsNullOrEmpty(), x => x.Value == iq.Value)
                .WhereIf(!iq.ValueCN.IsNullOrEmpty(), x => x.ValueCN == iq.ValueCN)
                .WhereIf(!iq.Description.IsNullOrEmpty(), x => x.Description == iq.Description)
                .WhereIf(iq.OptTypeId!=null, x => x.OptTypeId == iq.OptTypeId)
                .WhereIf(!iq.Code.IsNullOrEmpty(), x => x.Code == iq.Code)
                .WhereIf(iq.ChildrenTypeId != null, x => x.ChildrenTypeId == iq.ChildrenTypeId)
                .WhereIf(iq.ModuleTypeId != null, x => x.ModuleTypeId == iq.ModuleTypeId)
                .WhereIf(iq.ObjectTypeId != null, x => x.ObjectTypeId == iq.ObjectTypeId)
                .WhereIf(!iq.ConfigType.IsNullOrEmpty(), x => x.ConfigType == iq.ConfigType);

            return await query.OrderBy(x=>x.Sort).ToListAsync();
        }


        /// <summary>
        /// 修改排序
        /// </summary>
        /// <param name="sortDataList"></param>
        /// <returns></returns>
        public async Task<IResponseOutput> ChangeFrontAuditSort(List<FrontAuditSort> sortDataList)
        {
            foreach (var item in sortDataList)
            {
                await _frontAuditConfigRepository.BatchUpdateNoTrackingAsync(x => x.Id == item.Id, x => new FrontAuditConfig
                {
                    Sort = item.Sort
                });
            }
            await _frontAuditConfigRepository.SaveChangesAsync();
            return ResponseOutput.Ok();
        }

        /// <summary>
        /// 新增或者修改
        /// </summary>
        /// <param name="addOrEditFrontAuditConfig"></param>
        /// <returns></returns>
        public async Task<IResponseOutput> AddOrUpdateFrontAuditConfig(FrontAuditConfigAddOrEdit addOrEditFrontAuditConfig)
        {
         
            if (await _frontAuditConfigRepository.AnyAsync(x =>x.Identification!=string.Empty&& x.Identification == addOrEditFrontAuditConfig.Identification && x.Id != addOrEditFrontAuditConfig.Id&&x.ConfigType=="M"&& addOrEditFrontAuditConfig.ConfigType== "M"))
            {
                return ResponseOutput.NotOk("标识重复");
            }

            if (await _frontAuditConfigRepository.AnyAsync(x => x.Description == addOrEditFrontAuditConfig.Description && x.Id != addOrEditFrontAuditConfig.Id && x.ConfigType == "M" && addOrEditFrontAuditConfig.ConfigType == "M"))
            {
                return ResponseOutput.NotOk("名称重复");
            }

            var entity = await _frontAuditConfigRepository.InsertOrUpdateAsync(addOrEditFrontAuditConfig, true);

            return ResponseOutput.Ok(entity.Id.ToString());

        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="frontAuditConfigId"></param>
        /// <returns></returns>
        [HttpDelete("{frontAuditConfigId:guid}")]
        public async Task<IResponseOutput> DeleteFrontAuditConfig(Guid frontAuditConfigId)
        {
            if (await _frontAuditConfigRepository.AnyAsync(x => x.ParentId == frontAuditConfigId))
            {
                return ResponseOutput.NotOk("存在子类 不能删除");
            }
            var success = await _repository.BatchDeleteAsync<FrontAuditConfig>(t => t.Id == frontAuditConfigId);
            return ResponseOutput.Result(success);
        }


    }
}