/// <summary> /// Метод получает список диалогов с текущим пользователем. /// </summary> /// <param name="account">Логин пользователя.</param> /// <returns>Список диалогов.</returns> public async Task <GetResultDialogOutput> GetDialogsAsync(string account) { try { GetResultDialogOutput dialogsList = new GetResultDialogOutput(); List <DialogOutput> distinctDialogs = new List <DialogOutput>(); // Находит Id пользователя, для которого подтянуть список диалогов и мапит к типу UserOutput. MapperConfiguration config = new MapperConfiguration(cfg => cfg.CreateMap <UserEntity, UserOutput>()); Mapper mapper = new Mapper(config); UserOutput user = mapper.Map <UserOutput>(await _userService.GetUserByLogin(account)); if (string.IsNullOrEmpty(user.Id)) { throw new NotFoundUserException(account); } // Выберет список диалогов. var dialogs = await _postgre.DialogMembers .Join(_postgre.MainInfoDialogs, member => member.DialogId, info => info.DialogId, (member, info) => new { member, info }) .Select(res => new { res.info.DialogId, res.info.DialogName, res.member.Id, res.info.Created, res.member.User.UserName, res.member.User.UserRole, UserIcon = res.member.User.UserIcon ?? NoPhotoUrl.NO_PHOTO }) .ToListAsync(); // Если диалоги не найдены, то вернет пустой массив. if (!dialogs.Any()) { return(dialogsList); } // Находит и убирает дубли. int i = 0; foreach (object dialog in dialogs) { string jsonString = JsonSerializer.Serialize(dialog); DialogOutput resultDialog = JsonSerializer.Deserialize <DialogOutput>(jsonString); resultDialog.UserId ??= string.Empty; if (distinctDialogs.Count == 0 && !resultDialog.UserName.Equals(account)) { distinctDialogs.Add(resultDialog); } List <DialogOutput> dublicate = distinctDialogs .Where(u => u.UserId .Equals(dialogs[i].Id)) .ToList(); if (dublicate.Count != 0 || resultDialog.UserName.Equals(account)) { i++; continue; } distinctDialogs.Add(resultDialog); i++; } switch (user.UserRole) { // Диалог просматривает исполнитель, значит нужно удалить из массива других исполнителей. case UserRole.EXECUTOR: { DialogOutput itemToRemove = distinctDialogs .FirstOrDefault(r => r.UserRole .Equals(UserRole.EXECUTOR)); if (itemToRemove != null) { distinctDialogs.Remove(itemToRemove); } break; } // Диалог просматривает заказчик, значит нужно удалить из массива других заказчиков. case UserRole.CUSTOMER: { DialogOutput itemToRemove = distinctDialogs .FirstOrDefault(r => r.UserRole .Equals(UserRole.CUSTOMER)); if (itemToRemove != null) { distinctDialogs.Remove(itemToRemove); } break; } } foreach (object dialog in distinctDialogs) { string jsonString = JsonSerializer.Serialize(dialog); DialogOutput resultDialog = JsonSerializer.Deserialize <DialogOutput>(jsonString); // Подтянет последнее сообщение диалога для отображения в свернутом виде взяв первые 40 символов и далее ставит ... resultDialog.LastMessage = await _postgre.DialogMessages .Where(d => d.DialogId == resultDialog.DialogId) .OrderBy(o => o.Created) .Select(m => m.Message.Length > 40 ? string.Concat(m.Message.Substring(0, 40), "...") : m.Message) .LastOrDefaultAsync(); // Находит Id участников диалога по DialogId. IEnumerable <string> membersIds = await GetDialogMembers(resultDialog.DialogId); string executorId = string.Empty; if (membersIds == null) { throw new NotDialogMembersException(resultDialog.DialogId); } // Запишет логин собеседника. foreach (string id in membersIds.Where(id => !id.Equals(user.Id))) { resultDialog.UserName = await _userService.FindUserIdByLogin(id); // Запишет имя и фамилию, если они заполнены, иначе фронт будет использовать логин собеседника. UserOutput userInitial = await _userService.GetUserInitialsByIdAsync(id); if (string.IsNullOrEmpty(userInitial.FirstName) || string.IsNullOrEmpty(userInitial.LastName)) { continue; } resultDialog.FirstName = userInitial.FirstName; // Возьмет первую букву фамилии и поставит после нее точку. resultDialog.LastName = CommonMethodsService.SubstringLastName(userInitial.LastName); // Проставит фото профиля или фото по дефолту. resultDialog.UserIcon = userInitial.UserIcon ?? NoPhotoUrl.NO_PHOTO; } // Находит исполнителя в диалоге. foreach (string id in membersIds) { var dialogUser = await _postgre.Users .Where(u => u.Id.Equals(id)) .Select(u => new { u.UserRole, u.Id }) .FirstOrDefaultAsync(); // Пропустит, если не исполнитель. if (!dialogUser.UserRole.Equals(UserRole.EXECUTOR)) { continue; } executorId = dialogUser.Id; } // Исполнитель диалога найден, теперь подтянуть его ставку. resultDialog.Price = await _postgre.Responds .Where(r => r.ExecutorId.Equals(executorId)) .Select(res => string.Format("{0:0,0}", res.Price)) .FirstOrDefaultAsync(); // Если дата диалога совпадает с сегодняшней, то заполнит часы и минуты, иначе оставит их null. if (DateTime.Now.ToString("d").Equals(Convert.ToDateTime(resultDialog.Created).ToString("d"))) { // Запишет только часы и минуты. resultDialog.CalcTime = Convert.ToDateTime(resultDialog.Created).ToString("t"); } // Если дата диалога не совпадает с сегодняшней. else if (!DateTime.Now.ToString("d").Equals(Convert.ToDateTime(resultDialog.Created).ToString("d"))) { // Запишет только дату. resultDialog.CalcShortDate = Convert.ToDateTime(resultDialog.Created).ToString("d"); } // Форматирует дату убрав секунды. resultDialog.Created = Convert.ToDateTime(resultDialog.Created).ToString("g"); dialogsList.Dialogs.Add(resultDialog); } return(dialogsList); } catch (Exception ex) { Logger logger = new Logger(_db, ex.GetType().FullName, ex.Message, ex.StackTrace); await logger.LogCritical(); throw new Exception(ex.Message); } }
public async Task <IActionResult> GetDialogsAsync() { GetResultDialogOutput dialogs = await _chatService.GetDialogsAsync(GetUserName()); return(Ok(dialogs)); }