paiban/NPP.SmartSchedue.Api/Repositories/Time/ShiftRuleMappingRepository.cs
Asoka.Wang 21f044712c 1
2025-08-27 18:39:19 +08:00

93 lines
3.9 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 NPP.SmartSchedue.Api.Contracts;
using NPP.SmartSchedue.Api.Contracts.Domain.Time;
using NPP.SmartSchedue.Api.Core.Repositories;
using ZhonTai.Admin.Core.Db.Transaction;
namespace NPP.SmartSchedue.Api.Repositories.Time;
/// <summary>
/// 班次规则关联仓储
/// </summary>
public class ShiftRuleMappingRepository : AppRepositoryBase<ShiftRuleMappingEntity>, IShiftRuleMappingRepository
{
public ShiftRuleMappingRepository(UnitOfWorkManagerCloud uowm) : base(uowm)
{
}
/// <summary>
/// 根据班次ID获取有效的班次规则列表
/// 深度业务思考:
/// 1. 通过映射表Join关联获取规则
/// 2. 过滤启用状态和生效时间
/// 3. 按优先级排序
/// 高级工程师修复正确使用FreeSql Join语法
/// </summary>
public async Task<List<ShiftRuleEntity>> GetEffectiveShiftRulesAsync(long shiftId, DateTime? targetDate = null)
{
var currentDate = targetDate ?? DateTime.Now;
// 使用正确的FreeSql Join语法
var query = Orm.Select<ShiftRuleMappingEntity, ShiftRuleEntity>()
.LeftJoin((srm, sr) => srm.RuleId == sr.Id)
.Where((srm, sr) => srm.ShiftId == shiftId && srm.IsEnabled)
.Where((srm, sr) => srm.EffectiveStartTime == null || srm.EffectiveStartTime <= currentDate)
.Where((srm, sr) => srm.EffectiveEndTime == null || srm.EffectiveEndTime >= currentDate)
.Where((srm, sr) => sr.IsEnabled)
.Where((srm, sr) => sr.EffectiveStartTime == null || sr.EffectiveStartTime <= currentDate)
.Where((srm, sr) => sr.EffectiveEndTime == null || sr.EffectiveEndTime >= currentDate)
.OrderBy((srm, sr) => new { srm.ExecutionPriority, sr.DefaultPriority });
return await query.ToListAsync((srm, sr) => sr);
}
/// <summary>
/// 批量获取多个班次的规则映射
/// 深度业务思考:
/// 1. 一次查询获取所有班次的规则映射避免N+1查询
/// 2. 在内存中按班次ID分组提高性能
/// 3. 保持规则的优先级排序
/// </summary>
public async Task<Dictionary<long, List<ShiftRuleEntity>>> GetBatchShiftRulesAsync(List<long> shiftIds, DateTime? targetDate = null)
{
if (!shiftIds.Any())
return new Dictionary<long, List<ShiftRuleEntity>>();
var currentDate = targetDate ?? DateTime.Now;
// 查询所有相关的映射和规则数据 - 修复FreeSql Join语法
var mappingsWithRules = await Orm.Select<ShiftRuleMappingEntity, ShiftRuleEntity>()
.LeftJoin((srm, sr) => srm.RuleId == sr.Id)
.Where((srm, sr) => shiftIds.Contains(srm.ShiftId) && srm.IsEnabled)
.Where((srm, sr) => srm.EffectiveStartTime == null || srm.EffectiveStartTime <= currentDate)
.Where((srm, sr) => srm.EffectiveEndTime == null || srm.EffectiveEndTime >= currentDate)
.Where((srm, sr) => sr.IsEnabled)
.Where((srm, sr) => sr.EffectiveStartTime == null || sr.EffectiveStartTime <= currentDate)
.Where((srm, sr) => sr.EffectiveEndTime == null || sr.EffectiveEndTime >= currentDate)
.OrderBy((srm, sr) => srm.ShiftId)
.OrderBy((srm, sr) => srm.ExecutionPriority)
.OrderBy((srm, sr) => sr.DefaultPriority)
.ToListAsync((srm, sr) => new { mapping = srm, rule = sr });
// 按班次ID分组并构建结果字典
var result = new Dictionary<long, List<ShiftRuleEntity>>();
foreach (var shiftId in shiftIds)
{
result[shiftId] = new List<ShiftRuleEntity>();
}
foreach (var item in mappingsWithRules.Where(x => x.rule != null))
{
if (result.ContainsKey(item.mapping.ShiftId))
{
result[item.mapping.ShiftId].Add(item.rule);
}
}
return result;
}
}