using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using ZhonTai.Admin.Core.Dto;
using ZhonTai.Admin.Services;
using NPP.SmartSchedue.Api.Contracts.Services.Personnel;
using NPP.SmartSchedue.Api.Contracts.Services.Personnel.Input;
using NPP.SmartSchedue.Api.Contracts.Services.Personnel.Output;
using NPP.SmartSchedue.Api.Contracts.Services.Time;
using NPP.SmartSchedue.Api.Contracts.Services.Time.Input;
using NPP.SmartSchedue.Api.Services.Time;
using ZhonTai.DynamicApi;
using ZhonTai.DynamicApi.Attributes;
namespace NPP.SmartSchedue.Api.Services.Personnel;
///
/// 人员综合服务
///
[DynamicApi(Area = "app")]
public class PersonService : BaseService, IPersonService, IDynamicApi
{
private readonly IPersonnelWorkLimitService _personnelWorkLimitService;
private readonly IPersonnelQualificationService _personnelQualificationService;
private readonly IQualificationService _qualificationService;
private readonly IEmployeeLeaveService _employeeLeaveService;
private readonly IShiftService _shiftService;
private readonly ShiftUnavailabilityService _shiftUnavailabilityService;
public PersonService(
IPersonnelWorkLimitService personnelWorkLimitService,
IPersonnelQualificationService personnelQualificationService,
IQualificationService qualificationService,
IEmployeeLeaveService employeeLeaveService,
ShiftUnavailabilityService shiftUnavailabilityService,
IShiftService shiftService)
{
_personnelWorkLimitService = personnelWorkLimitService;
_personnelQualificationService = personnelQualificationService;
_qualificationService = qualificationService;
_employeeLeaveService = employeeLeaveService;
_shiftUnavailabilityService = shiftUnavailabilityService;
_shiftService = shiftService;
}
///
/// 根据资质IDs、班次ID、工作日期,查询非请假的、有资质的人员
///
/// 资质ID列表
/// 班次ID
/// 工作日期(将结合班次时间计算实际工作时间段)
///
public async Task> GetAvailablePersonnelAsync(
string qualificationIds,
long shiftId,
DateTime workStartTime)
{
var availablePersonnel = new List();
// 获取所有有指定资质的人员基础信息
var qualifiedPersonnelList = await _personnelQualificationService.GetPersonnelIdsByQualificationIdsAsync(qualificationIds);
var unavailablePersonnels = await _shiftUnavailabilityService.GetUnavailablePersonnelAsync(workStartTime, shiftId);
// 检查每个有资质的人员是否在指定时间段内有意愿
foreach (var personnel in qualifiedPersonnelList)
{
// 如果没有请假,则添加到可用人员列表
if (!unavailablePersonnels.Any(p => p == personnel.Id))
{
// 获取人员资质信息
var qualifications =
await _personnelQualificationService.GetActiveQualificationsByPersonnelIdAsync(personnel.Id);
availablePersonnel.Add(new AvailablePersonnelOutput
{
PersonnelId = personnel.Id,
PersonnelName = personnel.Name,
ShiftId = shiftId,
Qualifications = qualifications,
});
}
}
return availablePersonnel;
}
///
/// 检查人员是否具备指定资质
///
/// 人员ID
/// 资质ID
///
public async Task HasQualificationAsync(long personnelId, long qualificationId)
{
var input = new PageInput
{
Filter = new PersonnelQualificationGetPageInput
{
PersonnelId = personnelId,
QualificationId = qualificationId,
IsActive = true
},
PageSize = 1,
CurrentPage = 1
};
var result = await _personnelQualificationService.GetPageAsync(input);
return result.Total > 0;
}
///
/// 获取所有人员池(用于智能分配)
/// 深度业务思考:从资质表获取所有关联人员并去重,确保五层决策模型的完整性
///
/// 是否包含资质信息
/// 完整的人员池,用于后续的五层决策筛选
public async Task> GetAllPersonnelPoolAsync(bool includeQualifications = false)
{
try
{
// 从资质表获取所有有资质的人员ID,然后去重
// 这确保了获取的人员池都是有资质记录的人员
var allQualificationPersonnel = await _personnelQualificationService.GetAllPersonnelWithQualificationsAsync();
if (allQualificationPersonnel == null || !allQualificationPersonnel.Any())
{
return new List();
}
// 按人员ID去重分组,获取人员基础信息
var groupedByPersonnel = allQualificationPersonnel
.Where(pq => pq.PersonnelId > 0)
.GroupBy(pq => pq.PersonnelId)
.Select(g => g.First()) // 每个人员只取一条记录来获取基础信息
.ToList();
var personnelPoolOutputs = new List();
foreach (var qualificationRecord in groupedByPersonnel)
{
var poolOutput = new PersonnelPoolOutput
{
Id = qualificationRecord.PersonnelId,
PersonnelName = qualificationRecord.PersonnelName,
IsActive = true,
};
// 如果需要包含资质信息
if (includeQualifications)
{
poolOutput.Qualifications =
await _personnelQualificationService.GetActiveQualificationsByPersonnelIdAsync(
qualificationRecord.PersonnelId);
}
personnelPoolOutputs.Add(poolOutput);
}
return personnelPoolOutputs.OrderBy(p => p.PersonnelCode).ToList();
}
catch (Exception ex)
{
return new List();
}
}
}