Asoka.Wang 0a2e2d9b18 123
2025-09-02 18:52:35 +08:00

171 lines
6.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
/// <summary>
/// 人员综合服务
/// </summary>
[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;
}
/// <summary>
/// 根据资质IDs、班次ID、工作日期查询非请假的、有资质的人员
/// </summary>
/// <param name="qualificationIds">资质ID列表</param>
/// <param name="shiftId">班次ID</param>
/// <param name="workStartTime">工作日期(将结合班次时间计算实际工作时间段)</param>
/// <returns></returns>
public async Task<List<AvailablePersonnelOutput>> GetAvailablePersonnelAsync(
string qualificationIds,
long shiftId,
DateTime workStartTime)
{
var availablePersonnel = new List<AvailablePersonnelOutput>();
// 获取所有有指定资质的人员基础信息
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;
}
/// <summary>
/// 检查人员是否具备指定资质
/// </summary>
/// <param name="personnelId">人员ID</param>
/// <param name="qualificationId">资质ID</param>
/// <returns></returns>
public async Task<bool> HasQualificationAsync(long personnelId, long qualificationId)
{
var input = new PageInput<PersonnelQualificationGetPageInput>
{
Filter = new PersonnelQualificationGetPageInput
{
PersonnelId = personnelId,
QualificationId = qualificationId,
IsActive = true
},
PageSize = 1,
CurrentPage = 1
};
var result = await _personnelQualificationService.GetPageAsync(input);
return result.Total > 0;
}
/// <summary>
/// 获取所有人员池(用于智能分配)
/// 深度业务思考:从资质表获取所有关联人员并去重,确保五层决策模型的完整性
/// </summary>
/// <param name="includeQualifications">是否包含资质信息</param>
/// <returns>完整的人员池,用于后续的五层决策筛选</returns>
public async Task<List<PersonnelPoolOutput>> GetAllPersonnelPoolAsync(bool includeQualifications = false)
{
try
{
// 从资质表获取所有有资质的人员ID然后去重
// 这确保了获取的人员池都是有资质记录的人员
var allQualificationPersonnel = await _personnelQualificationService.GetAllPersonnelWithQualificationsAsync();
if (allQualificationPersonnel == null || !allQualificationPersonnel.Any())
{
return new List<PersonnelPoolOutput>();
}
// 按人员ID去重分组获取人员基础信息
var groupedByPersonnel = allQualificationPersonnel
.Where(pq => pq.PersonnelId > 0)
.GroupBy(pq => pq.PersonnelId)
.Select(g => g.First()) // 每个人员只取一条记录来获取基础信息
.ToList();
var personnelPoolOutputs = new List<PersonnelPoolOutput>();
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<PersonnelPoolOutput>();
}
}
}