121 lines
4.1 KiB
C#
121 lines
4.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Sozsoft.Platform.Entities;
|
|
using Sozsoft.Platform.Extensions;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Volo.Abp.Domain.Repositories;
|
|
using Volo.Abp.Identity;
|
|
|
|
namespace Sozsoft.Platform.OrgChart;
|
|
|
|
[Authorize]
|
|
[Route("api/app/org-chart")]
|
|
public class OrgChartAppService : PlatformAppService
|
|
{
|
|
private readonly IRepository<Department, Guid> _departmentRepository;
|
|
private readonly IRepository<JobPosition, Guid> _jobPositionRepository;
|
|
private readonly IIdentityUserRepository _userRepository;
|
|
|
|
public OrgChartAppService(
|
|
IRepository<Department, Guid> departmentRepository,
|
|
IRepository<JobPosition, Guid> jobPositionRepository,
|
|
IIdentityUserRepository userRepository)
|
|
{
|
|
_departmentRepository = departmentRepository;
|
|
_jobPositionRepository = jobPositionRepository;
|
|
_userRepository = userRepository;
|
|
}
|
|
|
|
[HttpGet("departments")]
|
|
public async Task<List<OrgChartNodeDto>> GetDepartmentsAsync()
|
|
{
|
|
var departments = await _departmentRepository.GetListAsync();
|
|
var jobPositions = await _jobPositionRepository.GetListAsync();
|
|
var users = await _userRepository.GetListAsync();
|
|
|
|
var jobById = jobPositions.ToDictionary(x => x.Id);
|
|
var topPositionByDepartment = new Dictionary<Guid, JobPosition>();
|
|
|
|
foreach (var department in departments)
|
|
{
|
|
var departmentPositions = jobPositions
|
|
.Where(x => x.DepartmentId == department.Id)
|
|
.ToList();
|
|
|
|
if (!departmentPositions.Any())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Top position means: no parent, parent missing, or parent belongs to another department.
|
|
var topCandidates = departmentPositions
|
|
.Where(position =>
|
|
!position.ParentId.HasValue ||
|
|
!jobById.ContainsKey(position.ParentId.Value) ||
|
|
jobById[position.ParentId.Value].DepartmentId != department.Id)
|
|
.OrderBy(position => position.Name)
|
|
.ToList();
|
|
|
|
var selectedTop = topCandidates.FirstOrDefault() ?? departmentPositions
|
|
.OrderBy(position => position.Name)
|
|
.First();
|
|
|
|
topPositionByDepartment[department.Id] = selectedTop;
|
|
}
|
|
|
|
var nodes = departments.Select(d => new OrgChartNodeDto
|
|
{
|
|
Id = d.Id,
|
|
Name = d.Name,
|
|
ParentId = d.ParentId,
|
|
Users = users
|
|
.Where(u =>
|
|
topPositionByDepartment.TryGetValue(d.Id, out var topPosition) &&
|
|
u.GetJobPositionId() == topPosition.Id)
|
|
.Select(u => new OrgChartUserDto
|
|
{
|
|
Id = u.Id,
|
|
FullName = u.GetFullName(),
|
|
Email = u.Email,
|
|
UserName = u.UserName,
|
|
})
|
|
.ToList(),
|
|
}).ToList();
|
|
|
|
return nodes;
|
|
}
|
|
|
|
[HttpGet("job-positions")]
|
|
public async Task<List<OrgChartNodeDto>> GetJobPositionsAsync()
|
|
{
|
|
var jobPositions = await _jobPositionRepository.GetListAsync();
|
|
var departments = await _departmentRepository.GetListAsync();
|
|
var users = await _userRepository.GetListAsync();
|
|
|
|
var deptDict = departments.ToDictionary(d => d.Id, d => d.Name);
|
|
|
|
var nodes = jobPositions.Select(jp => new OrgChartNodeDto
|
|
{
|
|
Id = jp.Id,
|
|
Name = jp.Name,
|
|
ParentId = jp.ParentId,
|
|
DepartmentId = jp.DepartmentId,
|
|
DepartmentName = deptDict.TryGetValue(jp.DepartmentId, out var name) ? name : null,
|
|
Users = users
|
|
.Where(u => u.GetJobPositionId() == jp.Id)
|
|
.Select(u => new OrgChartUserDto
|
|
{
|
|
Id = u.Id,
|
|
FullName = u.GetFullName(),
|
|
Email = u.Email,
|
|
UserName = u.UserName,
|
|
})
|
|
.ToList(),
|
|
}).ToList();
|
|
|
|
return nodes;
|
|
}
|
|
}
|