track/src/TrackCenter.Repository/Repositories/WarningRuleRepository.cs
zzh aeae900b5e feat: simplify transport warning to product+country with assessment SLA
AppKey-level scheme; scene matches one product and one country; stores assessment total hours (days×24) with migration SQL.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-01 11:13:38 +08:00

332 lines
12 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.Linq.Expressions;
using TrackCenter.Domain;
using TrackCenter.Domain.Aggregates.WarningAggregate;
using TrackCenter.Domain.Aggregates.WarningAggregate.Complete;
using TrackCenter.Domain.Aggregates.WarningAggregate.Return;
using TrackCenter.Domain.Aggregates.WarningAggregate.Transport;
using TrackCenter.Domain.Enums;
using TrackCenter.Domain.Extensions;
namespace TrackCenter.Repository.Repositories;
public class WarningRuleRepository : BasicRepository<WarningRuleEntity>, IWarningRuleRepository, ITransientDependency
{
#region 规则主体
public async Task<bool> CheckNameDuplicateAsync(int id, string appKey, string customer, string name, WarningRuleType warningType)
{
// 运输时效:AppKey + Name + Type(方案级,不按客户)
var query = Context.Queryable<WarningRuleEntity>()
.Where(x => x.AppKey == appKey
&& x.WarningType == (int) warningType
&& string.Equals(x.Name, name));
if (warningType != WarningRuleType.运输时效预警)
query = query.Where(x => x.Customer == customer);
var entity = await query.FirstAsync();
// 不重复
if (entity == null)
return false;
// 如果是修改,则要求查出来的和要修改的是同一个,否则视为重复
return entity.Id != id;
}
public async Task<bool> CheckEnableDuplicateAsync(int warningId, string appKey, string customer, WarningRuleType warningType)
{
// 运输时效:同一 AppKey + 类型仅允许一个启用方案
var query = Context.Queryable<WarningRuleEntity>()
.Where(x => x.AppKey == appKey
&& x.WarningType == (int) warningType
&& x.IsEnabled);
if (warningType != WarningRuleType.运输时效预警)
query = query.Where(x => x.Customer == customer);
var entity = await query.FirstAsync();
// 没有启用的规则
if (entity == null) return false;
// 已经启用和当前规则不同,视为启用重复,不允许操作
return entity.Id != warningId;
}
public async Task<int> UpsertReturnIdAsync(WarningRuleEntity entity)
{
if (entity.Id == 0)
{
return await Context.Insertable(entity)
.ExecuteReturnIdentityAsync();
}
var isUpdated = await Context.Updateable(entity)
.ExecuteCommandHasChangeAsync();
// 指定了id更新失败
if (!isUpdated)
{
throw new Exception($"{entity}更新失败");
}
return entity.Id;
}
public async Task<string> UpdateVersionAsync(WarningRuleEntity entity)
{
var version = VersionGenerate.GenVersion();
await Context.Updateable<WarningRuleEntity>()
.Where(x => x.Id == entity.Id)
.SetColumns(x => x.Version, version)
.ExecuteCommandHasChangeAsync();
return version;
}
public Task<List<WarningRuleEntity>> GetWarningRuleListAsync(string? appKey, string? customer, string? kpiname, bool? isEnabled, int? warningType)
{
return Context.Queryable<WarningRuleEntity>()
.WhereIF(!customer.IsNullOrWhiteSpace(), x => x.Customer.Contains(customer!))
.WhereIF(!appKey.IsNullOrWhiteSpace(), x => x.AppKey == appKey)
.WhereIF(warningType.HasValue, x => x.WarningType == warningType!.Value)
.WhereIF(isEnabled.HasValue, x => x.IsEnabled == isEnabled!.Value)
.WhereIF(!string.IsNullOrWhiteSpace(kpiname), x => x.Name.Contains(kpiname!))
.ToListAsync();
}
public async Task<WarningRuleEntity?> GetWarningRuleForEnabledAsync(string appKey, string customer, WarningRuleType warningType)
{
var warningRules = await Context.Queryable<WarningRuleEntity>()
.Where(x => x.Customer == customer
&& x.AppKey == appKey
&& x.WarningType == (int) warningType
&& x.IsEnabled
)
.ToListAsync();
return warningRules.FirstOrDefault();
}
public async Task<IReadOnlyDictionary<int, WarningRuleEntity>> GetWarningRuleForEnabledAsync(HashSet<(string AppKey, string Customer)> conditions, WarningRuleType warningType)
{
Expression<Func<WarningRuleEntity, bool>> baseExp = x => x.WarningType == (int) warningType && x.IsEnabled;
var exp = Expressionable.Create<WarningRuleEntity>();
foreach (var condition in conditions)
exp.Or(x => x.Customer == condition.Customer && x.AppKey == condition.AppKey);
var list = await Context.Queryable<WarningRuleEntity>()
.Where(baseExp.And(exp.ToExpression()))
.ToListAsync();
return list.Count == 0
? Empty<int, WarningRuleEntity>.Dict
: list.ToDictionary(x => x.Id);
}
public async Task<IReadOnlyDictionary<int, WarningRuleEntity>> GetWarningRuleForEnabledByAppKeysAsync(HashSet<string> appKeys, WarningRuleType warningType)
{
if (appKeys.Count == 0)
return Empty<int, WarningRuleEntity>.Dict;
var list = await Context.Queryable<WarningRuleEntity>()
.Where(x => x.WarningType == (int) warningType
&& x.IsEnabled
&& appKeys.Contains(x.AppKey))
.ToListAsync();
return list.Count == 0
? Empty<int, WarningRuleEntity>.Dict
: list.ToDictionary(x => x.Id);
}
public async Task<WarningRuleEntity?> GetWarningRuleByIdAsync(int id, WarningRuleType? warningType = null)
{
var result = await Context.Queryable<WarningRuleEntity>()
.Where(x => x.Id == id)
.WhereIF(warningType.HasValue, x => x.WarningType == (int) warningType!.Value)
.ToListAsync();
return result.FirstOrDefault();
}
#endregion
#region 运输时效预警规则
public Task<List<TransportWarningSceneEntity>> GetTransportSceneAsync(int warningId)
{
return Context.Queryable<TransportWarningSceneEntity>()
.Where(x => x.WarningId == warningId)
.ToListAsync();
}
public Task<List<TransportWarningSceneEntity>> GetTransportSceneAsync(Expression<Func<TransportWarningSceneEntity, bool>> whereExpression)
{
return Context.Queryable<TransportWarningSceneEntity>()
.Where(whereExpression)
.ToListAsync();
}
public async Task<TransportWarningSceneEntity?> GetTransportSceneAsync(int warningId, int sceneId)
{
var result = await Context.Queryable<TransportWarningSceneEntity>()
.Where(x => x.WarningId == warningId && x.Id == sceneId)
.ToListAsync();
return result.FirstOrDefault();
}
public Task<List<TransportWarningSceneRuleItemEntity>> GetTransportSceneRuleItemsAsync(int warningId, int sceneId)
{
return Context.Queryable<TransportWarningSceneRuleItemEntity>()
.Where(x => x.WarningId == warningId && x.TransportWarningSceneId == sceneId)
.ToListAsync();
}
public Task<List<TransportWarningSceneRuleItemEntity>> GetTransportSceneRuleItemsAsync(Expression<Func<TransportWarningSceneRuleItemEntity, bool>> whereExpression)
{
return Context.Queryable<TransportWarningSceneRuleItemEntity>()
.Where(whereExpression)
.ToListAsync();
}
public async Task<int> UpsertTransportSceneReturnIdAsync(TransportWarningSceneEntity entity)
{
if (entity.Id == 0)
{
return await Context.Insertable(entity)
.ExecuteReturnIdentityAsync();
}
var isUpdated = await Context.Updateable(entity)
.ExecuteCommandHasChangeAsync();
// 指定了id更新失败
if (!isUpdated)
{
throw new Exception($"{entity}更新失败");
}
return entity.Id;
}
public async Task<int> BulkUpdateTransportSceneRuleItemsAsync(List<TransportWarningSceneRuleItemEntity> entities)
{
return await Context.Updateable(entities)
.ExecuteCommandAsync();
}
public Task<int> BulkInsertTransportSceneRuleItemsAsync(List<TransportWarningSceneRuleItemEntity> entities)
{
return Context.Insertable(entities)
.ExecuteCommandAsync();
}
public Task<int> DeleteTransportSceneRuleItemsAsync(HashSet<int> ruleItemIds)
{
return Context.Deleteable<TransportWarningSceneRuleItemEntity>()
.Where(x => ruleItemIds.Contains(x.Id))
.ExecuteCommandAsync();
}
public async Task<bool> DeleteTransportSceneAsync(int warningId, int sceneId)
{
using var tran = TransactionHelper.GetReadCommitted();
await Context.Deleteable<TransportWarningSceneEntity>()
.Where(x => x.WarningId == warningId && x.Id == sceneId)
.ExecuteCommandAsync();
var r = await Context.Deleteable<TransportWarningSceneRuleItemEntity>()
.Where(x => x.TransportWarningSceneId == sceneId)
.ExecuteCommandHasChangeAsync();
tran.Complete();
return r;
}
#endregion
#region 回传时效预警规则
public Task<List<ReturnWarningRuleItemEntity>> GetReturnRuleItemsAsync(int warningId)
{
return Context.Queryable<ReturnWarningRuleItemEntity>()
.Where(x => x.WarningId == warningId)
.ToListAsync();
}
public Task<List<ReturnWarningRuleItemEntity>> GetReturnRuleItemsAsync(HashSet<int> ruleItemIds)
{
return Context.Queryable<ReturnWarningRuleItemEntity>()
.Where(x => ruleItemIds.Contains(x.Id))
.ToListAsync();
}
public Task<int> BulkInsertReturnRuleItemsAsync(List<ReturnWarningRuleItemEntity> entities)
{
return Context.Insertable(entities)
.ExecuteCommandAsync();
}
public async Task<int> BulkUpdateReturnRuleItemsAsync(List<ReturnWarningRuleItemEntity> entities)
{
return await Context.Updateable(entities)
.ExecuteCommandAsync();
}
public Task<int> DeleteReturnRuleItemsAsync(HashSet<int> ruleItemIds)
{
return Context.Deleteable<ReturnWarningRuleItemEntity>()
.Where(x => ruleItemIds.Contains(x.Id))
.ExecuteCommandAsync();
}
#endregion
#region 完整预警规则
public Task<List<CompleteWarningRuleItemEntity>> GetCompleteRuleItemsAsync(int warningId)
{
return Context.Queryable<CompleteWarningRuleItemEntity>()
.Where(x => x.WarningId == warningId)
.ToListAsync();
}
public Task<List<CompleteWarningRuleItemEntity>> GetCompleteRuleItemsAsync(HashSet<int> ruleItemIds)
{
return Context.Queryable<CompleteWarningRuleItemEntity>()
.Where(x => ruleItemIds.Contains(x.Id))
.ToListAsync();
}
public Task<List<CompleteWarningRuleItemEntity>> GetCompleteRuleItemsAsync(Expression<Func<CompleteWarningRuleItemEntity, bool>> whereExpression)
{
return Context.Queryable<CompleteWarningRuleItemEntity>()
.Where(whereExpression)
.ToListAsync();
}
public async Task<int> BulkUpdateCompleteRuleItemsAsync(List<CompleteWarningRuleItemEntity> entities)
{
return await Context.Updateable(entities)
.ExecuteCommandAsync();
}
public Task<int> BulkInsertCompleteRuleItemsAsync(List<CompleteWarningRuleItemEntity> entities)
{
return Context.Insertable(entities)
.ExecuteCommandAsync();
}
public Task<int> DeleteCompleteRuleItemsAsync(HashSet<int> ruleItemIds)
{
return Context.Deleteable<CompleteWarningRuleItemEntity>()
.Where(x => ruleItemIds.Contains(x.Id))
.ExecuteCommandAsync();
}
#endregion
}