using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NPP.SmartSchedue.Api.Contracts.Domain.Time;
using NPP.SmartSchedue.Api.Core.Repositories;
using ZhonTai.Admin.Core.Db;
using ZhonTai.Admin.Core.Db.Transaction;
using ZhonTai.Admin.Core.Repositories;
namespace NPP.SmartSchedue.Api.Repositories.Time;
///
/// 班次不可用标记仓储实现
/// 提供高性能的班次不可用数据访问方法
///
public class ShiftUnavailabilityRepository : AppRepositoryBase, IShiftUnavailabilityRepository
{
public ShiftUnavailabilityRepository(UnitOfWorkManagerCloud muowm) : base(muowm)
{
}
///
/// 获取指定员工在指定日期范围内的不可用记录
/// 用于网格视图数据加载,一次性获取整月数据避免N+1查询
///
public async Task> GetByPersonnelAndDateRangeAsync(long personnelId, DateTime startDate, DateTime endDate)
{
return await Select
.Where(x => x.PersonnelId == personnelId &&
x.Date >= startDate.Date &&
x.Date <= endDate.Date)
.OrderBy(x => x.Date)
.OrderBy(x => x.ShiftId)
.ToListAsync();
}
///
/// 获取指定日期和班次的不可用员工ID列表
/// 用于智能排班算法过滤不可用人员
///
public async Task> GetUnavailablePersonnelIdsAsync(DateTime date, long shiftId)
{
return await Select
.Where(x => x.Date.Date == date.Date && x.ShiftId == shiftId)
.GroupBy(x => x.PersonnelId) // 按员工分组,处理同一员工多条记录的情况
.ToListAsync(x => x.Key); // 只返回员工ID
}
///
/// 检查人员班次的意愿
///
///
///
///
///
public async Task CheckUnavailablePersonnelByShiftAsync(DateTime date, long shiftId, long personnelId)
{
return await Select
.AnyAsync(x => x.Date.Date == date.Date && x.ShiftId == shiftId && x.PersonnelId == personnelId );
}
///
/// 获取指定日期所有班次的不可用员工分布
/// 用于某日的批量人员可用性查询
///
public async Task>> GetDailyUnavailablePersonnelAsync(DateTime date)
{
var records = await Select
.Where(x => x.Date.Date == date.Date)
.GroupBy(x => new { x.ShiftId, x.PersonnelId })
.ToListAsync(x => new { x.Key.ShiftId, x.Key.PersonnelId });
return records
.GroupBy(x => x.ShiftId)
.ToDictionary(
g => g.Key,
g => g.Select(x => x.PersonnelId).ToList()
);
}
///
/// 批量获取日期范围内的不可用员工分布
/// 用于智能排班算法的批量优化查询
///
public async Task>>> GetRangeUnavailablePersonnelAsync(DateTime startDate, DateTime endDate)
{
var records = await Select
.Where(x => x.Date >= startDate.Date && x.Date <= endDate.Date)
.GroupBy(x => new { x.Date, x.ShiftId, x.PersonnelId })
.ToListAsync(x => new { x.Key.Date, x.Key.ShiftId, x.Key.PersonnelId });
return records
.GroupBy(x => x.Date.Date)
.ToDictionary(
dateGroup => dateGroup.Key,
dateGroup => dateGroup
.GroupBy(x => x.ShiftId)
.ToDictionary(
shiftGroup => shiftGroup.Key,
shiftGroup => shiftGroup.Select(x => x.PersonnelId).ToList()
)
);
}
///
/// 检查指定员工在指定日期和班次是否已有不可用记录
/// 用于避免重复插入和批量操作中的冲突检测
///
public async Task ExistsAsync(long personnelId, DateTime date, long shiftId)
{
return await Select
.Where(x => x.PersonnelId == personnelId &&
x.Date.Date == date.Date &&
x.ShiftId == shiftId)
.AnyAsync();
}
///
/// 删除指定条件的记录
/// 用于批量操作中的覆盖模式和数据清理
///
public async Task DeleteByConditionAsync(long personnelId, DateTime date, long? shiftId = null)
{
var query = Orm.Delete()
.Where(x => x.PersonnelId == personnelId && x.Date.Date == date.Date);
if (shiftId.HasValue)
{
query = query.Where(x => x.ShiftId == shiftId.Value);
}
return await query.ExecuteAffrowsAsync();
}
///
/// 获取统计信息
/// 按原因类型统计指定员工在指定日期范围内的不可用次数
///
public async Task> GetStatisticsAsync(long personnelId, DateTime startDate, DateTime endDate)
{
var results = await Select
.Where(x => x.PersonnelId == personnelId &&
x.Date >= startDate.Date &&
x.Date <= endDate.Date)
.GroupBy(x => x.ReasonType)
.ToListAsync(x => new { ReasonType = x.Key, Count = x.Count() });
return results.ToDictionary(x => x.ReasonType, x => x.Count);
}
}