feat: add TicketController with CRUD operations for ticket management

This commit is contained in:
MahanCh
2025-09-07 09:22:03 +03:30
parent 179ff95d54
commit 874bce1113

View File

@@ -0,0 +1,261 @@
using System.Security.Claims;
using _0_Framework.Application;
using AccountManagement.Application.Contracts.Account;
using AccountManagement.Application.Contracts.Ticket;
using AccountManagement.Domain.ClientResponseAgg;
using AccountManagement.Domain.TicketAgg;
using CompanyManagment.App.Contracts.Workshop;
using Microsoft.AspNetCore.Mvc;
using ServiceHost.BaseControllers;
namespace ServiceHost.Areas.Client.Controllers;
public class TicketController : ClientBaseController
{
private readonly IAuthHelper _authHelper;
private readonly ITicketApplication _ticketApplication;
private readonly IAccountApplication _accountApplication;
private readonly IPasswordHasher _passwordHasher;
private readonly IWorkshopApplication _workshopApplication;
public TicketController(
ITicketApplication ticketApplication,
IAuthHelper authHelper,
IAccountApplication accountApplication,
IPasswordHasher passwordHasher,
IWorkshopApplication workshopApplication)
{
_ticketApplication = ticketApplication;
_authHelper = authHelper;
_accountApplication = accountApplication;
_passwordHasher = passwordHasher;
_workshopApplication = workshopApplication;
}
[HttpGet]
public ActionResult<object> GetTickets([FromQuery] TicketSearchModel searchModel)
{
var workshopHash = User.FindFirstValue("WorkshopSlug");
var workshopId = _passwordHasher.SlugDecrypt(workshopHash);
if (workshopId <= 0)
{
return NotFound(new { message = "Workshop not found" });
}
var hasListTickets = _ticketApplication.GetTicketsForClients(searchModel).Count > 0;
var workshopFullName = _authHelper.GetWorkshopName();
var typesCountOfTicket = _ticketApplication.GetTypesCountOfTicketForClient(workshopId);
return Ok(new
{
hasListTickets,
workshopFullName,
typesCountOfTicket
});
}
[HttpGet("data")]
public ActionResult<object> GetTicketData(
[FromQuery] int pageIndex = 0,
[FromQuery] string status = "",
[FromQuery] string ticketNumber = "",
[FromQuery] string generalSearch = "")
{
var searchModel = new TicketSearchModel()
{
PageIndex = pageIndex,
Status = status,
TicketNumber = ticketNumber,
GeneralSearch = generalSearch,
};
var search = _ticketApplication.GetTicketsForClients(searchModel);
return Ok(new
{
data = search,
pageIndex = search.Count
});
}
[HttpGet("{ticketId}/details")]
public ActionResult<object> GetTicketDetails(long ticketId)
{
var result = _ticketApplication.GetDetailsForClient(ticketId);
if (result == null)
{
return NotFound(new { message = "Ticket not found" });
}
result.WorkshopName = _workshopApplication.GetDetails(result.WorkshopId).WorkshopFullName;
return Ok(result);
}
[HttpGet("{ticketId}/messages")]
public ActionResult<object> GetTicketMessages(long ticketId)
{
var result = _ticketApplication.GetDetailsForClient(ticketId);
if (result == null)
{
return NotFound(new { message = "Ticket not found" });
}
return Ok(new
{
ticketDetail = result
});
}
[HttpPost]
public ActionResult<object> CreateTicket([FromBody] CreateTicket command)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var accountInfo = _authHelper.CurrentAccountInfo();
command.SenderId = _authHelper.CurrentAccountId();
command.ContractingPartyName = accountInfo.Fullname;
command.WorkshopId = _passwordHasher.SlugDecrypt(User.FindFirstValue("WorkshopSlug"));
command.Description = command.Description?.Replace("\n", "<br>");
command.SubAccountId = accountInfo.SubAccountId;
var result = _ticketApplication.CreateTicket(command);
return Ok(new
{
isSuccedded = result.IsSuccedded,
message = result.Message
});
}
[HttpPost("upload")]
public ActionResult<object> UploadFile(IFormFile media)
{
if (media == null)
{
return BadRequest(new { message = "No file provided" });
}
var accountId = _authHelper.CurrentAccountId();
var operation = _ticketApplication.UploadMedia(media, accountId);
return Ok(new
{
isSuccedded = operation.IsSuccedded,
message = operation.Message,
id = operation.SendId,
});
}
[HttpDelete("media/{mediaId}")]
public ActionResult<object> DeleteFile(long mediaId)
{
var operation = _ticketApplication.RemoveMedia(mediaId);
return Ok(new
{
isSuccedded = operation.IsSuccedded,
message = operation.Message,
});
}
[HttpDelete("temp-files")]
public ActionResult<object> RemoveAllTempFiles()
{
var accId = _authHelper.CurrentAccountId();
var operation = new OperationResult();
_ticketApplication.RemoveTempUploadedFiles(accId);
operation.Succcedded();
return Ok(new
{
isSuccedded = operation.IsSuccedded,
message = operation.Message,
});
}
[HttpPost("{ticketId}/response")]
public ActionResult<object> SaveClientResponse(long ticketId, [FromBody] ResponseTicket command)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
command.Response = command.Response?.Replace("\n", "<br>");
var result = _ticketApplication.ClientResponseTicket(command);
return Ok(new
{
isSuccedded = result.IsSuccedded,
message = result.Message
});
}
[HttpGet("file")]
public IActionResult GetFile([FromQuery] string filePath, [FromQuery] long id)
{
if (string.IsNullOrEmpty(filePath))
{
return NotFound(new { message = "File path is required" });
}
if (!System.IO.File.Exists(filePath))
{
return NotFound(new { message = "File not found" });
}
var contentType = Tools.GetContentTypeImage(Path.GetExtension(filePath));
if (string.IsNullOrWhiteSpace(contentType))
{
byte[] fileContent = System.IO.File.ReadAllBytes(filePath);
var extension = Tools.GetContentType(Path.GetExtension(filePath));
return File(fileContent, extension, $"Task_{id}{Path.GetExtension(filePath)}");
}
else
{
return PhysicalFile(filePath, contentType);
}
}
[HttpGet("voice")]
public IActionResult GetVoice([FromQuery] string filePath)
{
if (string.IsNullOrEmpty(filePath))
{
return NotFound(new { message = "File path is required" });
}
if (!System.IO.File.Exists(filePath))
{
return NotFound(new { message = "Voice file not found" });
}
byte[] voiceContent = System.IO.File.ReadAllBytes(filePath);
return File(voiceContent, "audio/ogg", "Task_voice.ogg");
}
[HttpGet("picture")]
public IActionResult GetPicture([FromQuery] string filePath)
{
if (string.IsNullOrEmpty(filePath))
{
return NotFound(new { message = "File path is required" });
}
if (!System.IO.File.Exists(filePath))
{
return NotFound(new { message = "Picture not found" });
}
var contentType = Tools.GetContentTypeImage(Path.GetExtension(filePath));
return PhysicalFile(filePath, contentType);
}
}