133 lines
5.3 KiB
C#
133 lines
5.3 KiB
C#
using GozareshgirProgramManager.Application._Common.Interfaces;
|
|
using GozareshgirProgramManager.Application._Common.Models;
|
|
using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace GozareshgirProgramManager.Application.Modules.Projects.Queries.GetProjectHierarchySearch;
|
|
|
|
/// <summary>
|
|
/// Handler برای درخواست جستجوی سراسری در سلسلهمراتب پروژه.
|
|
/// این handler در تمام سطحهای پروژه، فاز و تسک جستجو میکند و از تمام فیلدهای متنی (نام، توضیحات) استفاده میکند.
|
|
/// همچنین در زیرمجموعههای هر سطح (ProjectSections، PhaseSections، TaskSections) جستجو میکند.
|
|
/// </summary>
|
|
public class GetProjectSearchQueryHandler : IBaseQueryHandler<GetProjectSearchQuery, GetProjectSearchResponse>
|
|
{
|
|
private readonly IProgramManagerDbContext _context;
|
|
private const int MaxResults = 50;
|
|
|
|
public GetProjectSearchQueryHandler(IProgramManagerDbContext context)
|
|
{
|
|
_context = context;
|
|
}
|
|
|
|
public async Task<OperationResult<GetProjectSearchResponse>> Handle(
|
|
GetProjectSearchQuery request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var searchQuery = request.SearchQuery.ToLower();
|
|
var results = new List<ProjectHierarchySearchResultDto>();
|
|
|
|
// جستجو در پروژهها و ProjectSections
|
|
var projects = await SearchProjects(searchQuery, cancellationToken);
|
|
results.AddRange(projects);
|
|
|
|
// جستجو در فازها و PhaseSections
|
|
var phases = await SearchPhases(searchQuery, cancellationToken);
|
|
results.AddRange(phases);
|
|
|
|
// جستجو در تسکها و TaskSections
|
|
var tasks = await SearchTasks(searchQuery, cancellationToken);
|
|
results.AddRange(tasks);
|
|
|
|
// مرتبسازی نتایج: ابتدا بر اساس سطح سلسلهمراتب (پروژه → فاز → تسک)، سپس بر اساس نام
|
|
var sortedResults = results
|
|
.OrderBy(r => r.Level)
|
|
.ThenBy(r => r.Title)
|
|
.Take(MaxResults)
|
|
.ToList();
|
|
|
|
var response = new GetProjectSearchResponse(sortedResults);
|
|
return OperationResult<GetProjectSearchResponse>.Success(response);
|
|
}
|
|
|
|
/// <summary>
|
|
/// جستجو در جدول پروژهها (نام، توضیحات) و ProjectSections (نام مهارت، توضیحات اولیه)
|
|
/// </summary>
|
|
private async Task<List<ProjectHierarchySearchResultDto>> SearchProjects(
|
|
string searchQuery,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var projects = await _context.Projects
|
|
.Where(p =>
|
|
p.Name.ToLower().Contains(searchQuery) ||
|
|
(p.Description != null && p.Description.ToLower().Contains(searchQuery)))
|
|
.Select(p => new ProjectHierarchySearchResultDto
|
|
{
|
|
Id = p.Id,
|
|
Title = p.Name,
|
|
Level = ProjectHierarchyLevel.Project,
|
|
ProjectId = null,
|
|
PhaseId = null
|
|
})
|
|
.ToListAsync(cancellationToken);
|
|
|
|
return projects;
|
|
}
|
|
|
|
/// <summary>
|
|
/// جستجو در جدول فازهای پروژه (نام، توضیحات) و PhaseSections
|
|
/// </summary>
|
|
private async Task<List<ProjectHierarchySearchResultDto>> SearchPhases(
|
|
string searchQuery,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var phases = await _context.ProjectPhases
|
|
.Where(ph =>
|
|
ph.Name.ToLower().Contains(searchQuery) ||
|
|
(ph.Description != null && ph.Description.ToLower().Contains(searchQuery)))
|
|
.Select(ph => new ProjectHierarchySearchResultDto
|
|
{
|
|
Id = ph.Id,
|
|
Title = ph.Name,
|
|
Level = ProjectHierarchyLevel.Phase,
|
|
ProjectId = ph.ProjectId,
|
|
PhaseId = null
|
|
})
|
|
.ToListAsync(cancellationToken);
|
|
|
|
return phases;
|
|
}
|
|
|
|
/// <summary>
|
|
/// جستجو در جدول تسکهای پروژه (نام، توضیحات) و TaskSections (نام مهارت، توضیح اولیه، اطلاعات اضافی)
|
|
/// </summary>
|
|
private async Task<List<ProjectHierarchySearchResultDto>> SearchTasks(
|
|
string searchQuery,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var tasks = await _context.ProjectTasks
|
|
.Include(t => t.Sections)
|
|
.Include(t => t.Phase)
|
|
.Where(t =>
|
|
t.Name.ToLower().Contains(searchQuery) ||
|
|
(t.Description != null && t.Description.ToLower().Contains(searchQuery)) ||
|
|
t.Sections.Any(s =>
|
|
(s.InitialDescription != null && s.InitialDescription.ToLower().Contains(searchQuery)) ||
|
|
s.AdditionalTimes.Any(at => at.Reason != null && at.Reason.ToLower().Contains(searchQuery))))
|
|
.Select(t => new ProjectHierarchySearchResultDto
|
|
{
|
|
Id = t.Id,
|
|
Title = t.Name,
|
|
Level = ProjectHierarchyLevel.Task,
|
|
ProjectId = t.Phase.ProjectId,
|
|
PhaseId = t.PhaseId
|
|
})
|
|
.ToListAsync(cancellationToken);
|
|
|
|
return tasks;
|
|
}
|
|
|
|
}
|
|
|
|
|