151 lines
5.6 KiB
C#
151 lines
5.6 KiB
C#
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;
|
||
|
||
/// <summary>
|
||
/// 班次不可用标记仓储实现
|
||
/// 提供高性能的班次不可用数据访问方法
|
||
/// </summary>
|
||
public class ShiftUnavailabilityRepository : AppRepositoryBase<ShiftUnavailabilityEntity>, IShiftUnavailabilityRepository
|
||
{
|
||
public ShiftUnavailabilityRepository(UnitOfWorkManagerCloud muowm) : base(muowm)
|
||
{
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取指定员工在指定日期范围内的不可用记录
|
||
/// 用于网格视图数据加载,一次性获取整月数据避免N+1查询
|
||
/// </summary>
|
||
public async Task<List<ShiftUnavailabilityEntity>> 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();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取指定日期和班次的不可用员工ID列表
|
||
/// 用于智能排班算法过滤不可用人员
|
||
/// </summary>
|
||
public async Task<List<long>> 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
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查人员班次的意愿
|
||
/// </summary>
|
||
/// <param name="date"></param>
|
||
/// <param name="shiftId"></param>
|
||
/// <param name="personnelId"></param>
|
||
/// <returns></returns>
|
||
public async Task<bool> CheckUnavailablePersonnelByShiftAsync(DateTime date, long shiftId, long personnelId)
|
||
{
|
||
return await Select
|
||
.AnyAsync(x => x.Date.Date == date.Date && x.ShiftId == shiftId && x.PersonnelId == personnelId );
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取指定日期所有班次的不可用员工分布
|
||
/// 用于某日的批量人员可用性查询
|
||
/// </summary>
|
||
public async Task<Dictionary<long, List<long>>> 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()
|
||
);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 批量获取日期范围内的不可用员工分布
|
||
/// 用于智能排班算法的批量优化查询
|
||
/// </summary>
|
||
public async Task<Dictionary<DateTime, Dictionary<long, List<long>>>> 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()
|
||
)
|
||
);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查指定员工在指定日期和班次是否已有不可用记录
|
||
/// 用于避免重复插入和批量操作中的冲突检测
|
||
/// </summary>
|
||
public async Task<bool> ExistsAsync(long personnelId, DateTime date, long shiftId)
|
||
{
|
||
return await Select
|
||
.Where(x => x.PersonnelId == personnelId &&
|
||
x.Date.Date == date.Date &&
|
||
x.ShiftId == shiftId)
|
||
.AnyAsync();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 删除指定条件的记录
|
||
/// 用于批量操作中的覆盖模式和数据清理
|
||
/// </summary>
|
||
public async Task<int> DeleteByConditionAsync(long personnelId, DateTime date, long? shiftId = null)
|
||
{
|
||
var query = Orm.Delete<ShiftUnavailabilityEntity>()
|
||
.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();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取统计信息
|
||
/// 按原因类型统计指定员工在指定日期范围内的不可用次数
|
||
/// </summary>
|
||
public async Task<Dictionary<int, int>> 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);
|
||
}
|
||
} |