This commit is contained in:
mmrbnjd
2025-08-03 17:22:49 +03:30
parent 381c877bc3
commit dace739e46
6 changed files with 192 additions and 23 deletions

View File

@@ -272,11 +272,44 @@ namespace Hushian.Application.Services
return Response; return Response;
} }
public async Task<bool> FinishChat(int ChatID) public async Task<bool> FinishChat(int ChatID, int CompanyID)
{ {
var convModel = await _ConversationRepository.Get() var convModel = await _ConversationRepository.Get()
.Include(inc => inc.ConversationResponses) .Include(inc => inc.ConversationResponses)
.FirstOrDefaultAsync(w => w.ID == ChatID); .FirstOrDefaultAsync(w => w.ID == ChatID && w.CompanyID==CompanyID);
if (convModel != null && convModel.Status != ConversationStatus.Finished)
{
convModel.Status = ConversationStatus.Finished;
convModel.FinishedDateTime = DateTime.Now;
return await _ConversationRepository.UPDATEBool(convModel);
}
return true;
}
public async Task<bool> OpenChat(int ChatID, int CompanyID,int? ExperID)
{
var convModel = await _ConversationRepository.Get()
.Include(inc => inc.ConversationResponses)
.FirstOrDefaultAsync(w =>
w.ID == ChatID
&& w.CompanyID == CompanyID
&& ExperID.HasValue ? w.ConversationResponses.Any(a=>a.ExperID==ExperID.GetValueOrDefault()) :true);
if (convModel != null && convModel.Status == ConversationStatus.Finished)
{
convModel.Status = ConversationStatus.InProgress;
convModel.FinishedDateTime = null;
return await _ConversationRepository.UPDATEBool(convModel);
}
return true;
}
public async Task<bool> FinishChatFromUser(int ChatID, int userID)
{
var convModel = await _ConversationRepository.Get()
.Include(inc => inc.ConversationResponses)
.FirstOrDefaultAsync(w => w.ID == ChatID && w.UserID == userID);
if (convModel != null && convModel.Status != ConversationStatus.Finished) if (convModel != null && convModel.Status != ConversationStatus.Finished)
{ {

View File

@@ -122,11 +122,60 @@ namespace Hushian.WebApi.Controllers.v1
return Response.Success ? Ok(Response.Value) return Response.Success ? Ok(Response.Value)
: BadRequest(Response.Errors); : BadRequest(Response.Errors);
} }
[HttpGet("ChatIsFinish/{ChatID}")] [HttpPut("ChatIsFinish/{ChatID}")]
[Authorize(Roles = "Company,Exper")] [Authorize(Roles = "Company,Exper")]
public async Task<ActionResult> ChatIsFinish(int ChatID) public async Task<ActionResult> ChatIsFinish(int ChatID)
{ {
return await _chatService.FinishChat(ChatID) ? NoContent()
int CompanyID = 0;
if (User.IsInRole("Exper"))
{
string strExperID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
int ExperID = Convert.ToInt32(strExperID);
CompanyID = await _experService.GetCompanyIDExper(ExperID);
}
else if (User.IsInRole("Company"))
{
string strCompanyID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
CompanyID = Convert.ToInt32(strCompanyID);
}
return await _chatService.FinishChat(ChatID, CompanyID) ? NoContent()
: BadRequest(new List<string> { "خطا در بروزرسانی وضعیت" });
}
[HttpPut("OpenChat/{ChatID}")]
[Authorize(Roles = "Company,Exper")]
public async Task<ActionResult> OpenChat(int ChatID)
{
int CompanyID = 0;
int? ExperID =null;
if (User.IsInRole("Exper"))
{
string strExperID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
ExperID = Convert.ToInt32(strExperID);
CompanyID = await _experService.GetCompanyIDExper(ExperID.GetValueOrDefault());
}
else if (User.IsInRole("Company"))
{
string strCompanyID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
CompanyID = Convert.ToInt32(strCompanyID);
}
return await _chatService.OpenChat(ChatID, CompanyID, ExperID) ? NoContent()
: BadRequest(new List<string> { "خطا در بروزرسانی وضعیت" });
}
[HttpPut("ChatIsFinishFromUser/{ChatID}")]
[Authorize(Roles = "User")]
public async Task<ActionResult> ChatIsFinishFromUser(int ChatID)
{
string strUserID = User.Claims.Where(w => w.Type == CustomClaimTypes.Uid).Select(s => s.Value).First();
int UserID = Convert.ToInt32(strUserID);
return await _chatService.FinishChatFromUser(ChatID, UserID) ? NoContent()
: BadRequest(new List<string> { "خطا در بروزرسانی وضعیت" }); : BadRequest(new List<string> { "خطا در بروزرسانی وضعیت" });
} }
[HttpPut("MarkAsReadChatItem/{ConversationItemID}")] [HttpPut("MarkAsReadChatItem/{ConversationItemID}")]

View File

@@ -27,7 +27,7 @@
"Key": "84322CFB66934ECC86D547C5CF4F2EFC", "Key": "84322CFB66934ECC86D547C5CF4F2EFC",
"Audience": "MMRbnjd", "Audience": "MMRbnjd",
"Issuer": "MMRbnjd", "Issuer": "MMRbnjd",
"DurationInMinutes": 60 "DurationInMinutes": 6000
}, },
"AllowedHosts": "*" "AllowedHosts": "*"
} }

View File

@@ -8,6 +8,8 @@
@inject GroupService groupService @inject GroupService groupService
@inject UserService userService @inject UserService userService
@inject IJSRuntime JS @inject IJSRuntime JS
@inject ToastService toastService
<ConfirmDialog @ref="dialog" />
<PageTitle>گفتمان</PageTitle> <PageTitle>گفتمان</PageTitle>
<div class="container-fluid"> <div class="container-fluid">
<div class="row" style="height:85vh"> <div class="row" style="height:85vh">
@@ -64,11 +66,11 @@
<Badge Color="BadgeColor.Info" VisuallyHiddenText="Visually hidden text for Info">@item.GroupName</Badge> <Badge Color="BadgeColor.Info" VisuallyHiddenText="Visually hidden text for Info">@item.GroupName</Badge>
</div> </div>
} }
<div class="item-time"> <div class="item-time">
<small class="time-text">@item.LastMsgdate</small> <small class="time-text">@item.LastMsgdate</small>
<small class="time-text">@item.LastMsgtime</small> <small class="time-text">@item.LastMsgtime</small>
</div> </div>
</div> </div>
<div class="item-message">@item.LastText</div> <div class="item-message">@item.LastText</div>
@@ -152,11 +154,7 @@
@if (ChatCurrent.status == Common.Enums.ConversationStatus.InProgress) @if (ChatCurrent.status == Common.Enums.ConversationStatus.InProgress)
{ {
<Button Color="ButtonColor.Danger" Size=ButtonSize.ExtraSmall Outline="true" Class="finish-conversation-btn" <Button Color="ButtonColor.Danger" Size=ButtonSize.ExtraSmall Outline="true" Class="finish-conversation-btn"
@onclick="async()=> @onclick="CloseChat">
{
if(await chatService.ChatIsFinish(ChatCurrent.ID))
ChatCurrent.status=Common.Enums.ConversationStatus.Finished;
}">
<Icon Name="IconName.Escape" /> اتمام گفتگو <Icon Name="IconName.Escape" /> اتمام گفتگو
</Button> </Button>
@@ -167,7 +165,8 @@
else if (ChatCurrent.status == Common.Enums.ConversationStatus.Finished else if (ChatCurrent.status == Common.Enums.ConversationStatus.Finished
&& (CurrentUser.Role == "Company" || ChatCurrent.ExperID == CurrentUser.ExperID)) && (CurrentUser.Role == "Company" || ChatCurrent.ExperID == CurrentUser.ExperID))
{ {
<Button Color="ButtonColor.Success" Size=ButtonSize.ExtraSmall Outline="true" Class="finish-conversation-btn"> <Button Color="ButtonColor.Success" Size=ButtonSize.ExtraSmall Outline="true" Class="finish-conversation-btn"
@onclick="OpenChat">
<Icon Name="IconName.Escape" /> باز کردن گفتگو <Icon Name="IconName.Escape" /> باز کردن گفتگو
</Button> </Button>
@@ -283,7 +282,7 @@
bool chatloading = false; bool chatloading = false;
string SelectedChatUserName = "مهدی ربیع نژاد"; string SelectedChatUserName = "مهدی ربیع نژاد";
private bool _shouldObserveVisibility = false; private bool _shouldObserveVisibility = false;
private ConfirmDialog dialog = default!;
} }
@functions { @functions {
@@ -351,7 +350,7 @@
chatloading = true; chatloading = true;
SelectedChatUserName = "در حال گفتگو با " + chatItem.UserFullName; SelectedChatUserName = "در حال گفتگو با " + chatItem.UserFullName;
ChatCurrent = chatItem; ChatCurrent = chatItem;
_shouldObserveVisibility = true; // فعال کن تا در OnAfterRenderAsync صدا زده بشه _shouldObserveVisibility = true; // فعال کن تا در OnAfterRenderAsync صدا زده بشه
StateHasChanged(); // مجبور کن Blazor رندر کنه StateHasChanged(); // مجبور کن Blazor رندر کنه
@@ -367,8 +366,50 @@
msg.IsRead = true; msg.IsRead = true;
await chatService.MarkAsReadChatItemAsync(id); await chatService.MarkAsReadChatItemAsync(id);
} }
// StateHasChanged(); // StateHasChanged();
await Task.CompletedTask; await Task.CompletedTask;
}
async Task OpenChat()
{
if (CurrentUser.Role == "Company" || CurrentUser.Role == "Exper" && ChatCurrent.ExperID==CurrentUser.ExperID)
{
if (ChatCurrent.status != Common.Enums.ConversationStatus.Finished) return;
if (await chatService.OpenChat(ChatCurrent.ID))
{
ChatCurrent.status = Common.Enums.ConversationStatus.InProgress;
StateHasChanged();
}
}
else toastService.Notify(new ToastMessage(ToastType.Danger, "دسترسی به این گفتگو ندارید"));
}
async Task CloseChat()
{
if (ChatCurrent.status == Common.Enums.ConversationStatus.Finished) return;
var options = new ConfirmDialogOptions
{
YesButtonText = "بله",
YesButtonColor = ButtonColor.Success,
NoButtonText = "انصراف",
NoButtonColor = ButtonColor.Danger
};
var confirmation = await dialog.ShowAsync(
title: "پایان دادن به گفتگو",
message1: "اطمینان دارید ؟",
confirmDialogOptions: options);
if (confirmation)
{
if (await chatService.ChatIsFinish(ChatCurrent.ID))
{
ChatCurrent.status = Common.Enums.ConversationStatus.Finished;
StateHasChanged();
}
}
} }
} }

View File

@@ -16,6 +16,8 @@
@inject IJSRuntime JS @inject IJSRuntime JS
@inject ToastService toastService @inject ToastService toastService
@layout UserPanelLayout @layout UserPanelLayout
<ConfirmDialog @ref="dialog" />
<div class="container-fluid"> <div class="container-fluid">
<div class="row" style="height:85vh"> <div class="row" style="height:85vh">
@if (IsEndFirstProcess) @if (IsEndFirstProcess)
@@ -33,11 +35,11 @@
{ {
@if (LastOpenChat.status == Common.Enums.ConversationStatus.InProgress) @if (LastOpenChat.status == Common.Enums.ConversationStatus.InProgress)
{ {
<Button Color="ButtonColor.Danger" Size=ButtonSize.ExtraSmall Outline="true" Class="finish-conversation-btn"> <Button Color="ButtonColor.Danger" Size=ButtonSize.ExtraSmall Outline="true" @onclick="CloseChat" Class="finish-conversation-btn">
<Icon Name="IconName.Escape" Class="me-1" /> اتمام گفتگو <Icon Name="IconName.Escape" Class="me-1" /> اتمام گفتگو
</Button> </Button>
} }
<Button Color="ButtonColor.Success" Size=ButtonSize.ExtraSmall Outline="true" Class="finish-conversation-btn"> <Button Color="ButtonColor.Success" Size=ButtonSize.ExtraSmall Outline="true" @onclick="NewChat" Class="finish-conversation-btn">
<Icon Name="IconName.ChatDots" Class="me-1" /> گفتگو جدید <Icon Name="IconName.ChatDots" Class="me-1" /> گفتگو جدید
</Button> </Button>
} }
@@ -105,7 +107,7 @@
@foreach (var group in CompanyGroups) @foreach (var group in CompanyGroups)
{ {
<div class="group-card @(GroupID == group.ID ? "selected" : "")" <div class="group-card @(GroupID == group.ID ? "selected" : "")"
@onclick="() => SelectGroup(group.ID)"> @onclick="() => SelectGroup(group.ID)">
<div class="group-card-content"> <div class="group-card-content">
@if (group.img == null || group.img.Length == 0) @if (group.img == null || group.img.Length == 0)
{ {
@@ -133,7 +135,7 @@
<!-- B2: Message input --> <!-- B2: Message input -->
<div class="message-input-container" id="B2"> <div class="message-input-container" id="B2">
<div class="input-wrapper"> <div class="input-wrapper">
<input type="text" @bind-value="MsgInput" class="message-input" placeholder="پیام خود را بنویسید..." /> <input type="text" @bind-value="MsgInput" class="message-input" placeholder="پیام خود را بنویسید..." @onkeydown="HandleKeyDown" />
<Button Color="ButtonColor.Primary" Size=ButtonSize.Small @onclick="OnClickSendMsg" Class="send-btn"> <Button Color="ButtonColor.Primary" Size=ButtonSize.Small @onclick="OnClickSendMsg" Class="send-btn">
<Icon Name="IconName.Send" /> <Icon Name="IconName.Send" />
</Button> </Button>
@@ -170,6 +172,7 @@
@code { @code {
[Parameter] public int CompanyID { get; set; } [Parameter] public int CompanyID { get; set; }
[Parameter] public int? ChatID { get; set; } [Parameter] public int? ChatID { get; set; }
private ConfirmDialog dialog = default!;
private bool _shouldObserveVisibility = false; private bool _shouldObserveVisibility = false;
int? GroupID = null; int? GroupID = null;
@@ -297,7 +300,7 @@
{ {
if (ChatID.HasValue) LastOpenChat = await ChatService.Getchat(ChatID.GetValueOrDefault()); if (ChatID.HasValue) LastOpenChat = await ChatService.Getchat(ChatID.GetValueOrDefault());
else LastOpenChat = LastOpenChat = await ChatService.GetLastOpenChatInCompany(CompanyID); else LastOpenChat = LastOpenChat = await ChatService.GetLastOpenChatInCompany(CompanyID);
if (LastOpenChat != null) if (LastOpenChat != null)
{ {
@@ -337,6 +340,37 @@
await JS.InvokeVoidAsync("autoScrollToNewMessage"); await JS.InvokeVoidAsync("autoScrollToNewMessage");
} }
} }
}
async Task NewChat()
{
LastOpenChat = null;
}
async Task CloseChat()
{
var options = new ConfirmDialogOptions
{
YesButtonText = "بله",
YesButtonColor = ButtonColor.Success,
NoButtonText = "انصراف",
NoButtonColor = ButtonColor.Danger
};
var confirmation = await dialog.ShowAsync(
title: "پایان دادن به گفتگو",
message1: "اطمینان دارید ؟",
confirmDialogOptions: options);
if (confirmation)
{
if (await chatService.ChatIsFinishFromUser(LastOpenChat.ID))
{
LastOpenChat.status = Common.Enums.ConversationStatus.Finished;
StateHasChanged();
}
}
} }
async Task Logout() async Task Logout()
{ {
@@ -345,7 +379,6 @@
IsLogin = false; IsLogin = false;
StateHasChanged(); StateHasChanged();
} }
async Task SelectGroup(int groupId) async Task SelectGroup(int groupId)
{ {
GroupID = groupId; GroupID = groupId;
@@ -353,7 +386,10 @@
} }
private string GetImageSource(byte[] bytes) private string GetImageSource(byte[] bytes)
=> $"data:image/jpeg;base64,{Convert.ToBase64String(bytes)}"; => $"data:image/jpeg;base64,{Convert.ToBase64String(bytes)}";
private async Task HandleKeyDown(KeyboardEventArgs e)
{
if (e.Key == "Enter") await OnClickSendMsg();
}
} }
<style> <style>

View File

@@ -62,11 +62,21 @@ namespace HushianWebApp.Service
return null; return null;
} }
public async Task<bool> OpenChat(int ChatID)
{
var response = await _baseController.Put($"{BaseRoute}OpenChat/{ChatID}");
return response.IsSuccessStatusCode;
}
public async Task<bool> ChatIsFinish(int ChatID) public async Task<bool> ChatIsFinish(int ChatID)
{ {
var response = await _baseController.Put($"{BaseRoute}ChatIsFinish/{ChatID}"); var response = await _baseController.Put($"{BaseRoute}ChatIsFinish/{ChatID}");
return response.IsSuccessStatusCode; return response.IsSuccessStatusCode;
} }
public async Task<bool> ChatIsFinishFromUser(int ChatID)
{
var response = await _baseController.Put($"{BaseRoute}ChatIsFinishFromUser/{ChatID}");
return response.IsSuccessStatusCode;
}
public async Task<bool> MarkAsReadChatItemAsync(int ID) public async Task<bool> MarkAsReadChatItemAsync(int ID)
{ {
var response = await _baseController.Put($"{BaseRoute}MarkAsReadChatItem/{ID}"); var response = await _baseController.Put($"{BaseRoute}MarkAsReadChatItem/{ID}");