admin/src/Oms.Application/Services/Orders/Issues/AutoTriggerRuntimeService.cs
2026-10-10 16:41:28 +08:00

154 lines
5.6 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 Fake.DependencyInjection;
using Microsoft.Extensions.Logging;
using Oms.Application.Messaging.OrderSideEffects;
using Oms.Domain.ChannelsAggregate.Consts;
using Oms.Domain.ChannelsAggregate.Entities;
using Oms.Domain.ChannelsAggregate.Repositories;
using Oms.Domain.OrdersAggregate.Entities;
using Oms.Domain.OrdersAggregate.Repositories;
using Oms.Domain.Shared.Enums;
namespace Oms.Application.Services.Orders.Issues;
public class AutoTriggerRuntimeService(
IAutoTriggerRepository autoTriggerRepository,
IOrderRepository orderRepository,
OrderAutoTriggerService orderAutoTriggerService,
OrderExceptionWorkflowService exceptionWorkflowService,
OrderIssueNotificationService issueNotificationService,
IOrderSideEffectEventPublisher sideEffectEventPublisher,
ILogger<AutoTriggerRuntimeService> logger) : IScopedDependency
{
private const string InterceptOperation = "拦截";
/// <summary>
/// 投递自动触发事件(须在事务 UoW 内调用,写入 Outbox)。
/// </summary>
public Task EnqueueFireAsync(int orderId, AutoTriggerTiming timing, int operatorUserId) =>
orderId <= 0
? Task.CompletedTask
: sideEffectEventPublisher.PublishAutoTriggerFireAsync(orderId, timing, operatorUserId);
public async Task FireAsync(Order order, AutoTriggerTiming timing, int operatorUserId)
{
if (order.Id <= 0)
{
return;
}
var context = await orderAutoTriggerService.BuildPostCommitContextAsync(order);
var triggers = await autoTriggerRepository.GetListAsync(x => x.Status == EnableStatus.Enabled);
var orderedTriggers = triggers
.Where(x => AutoTriggerTimingCodes.Matches(x.TriggerTiming, timing))
.Select(x => (Trigger: x, Priority: AutoTriggerRuleResolver.GetPriority(x)))
.OrderBy(x => x.Priority)
.ThenBy(x => x.Trigger.Id)
.Select(x => x.Trigger)
.ToList();
foreach (var trigger in orderedTriggers)
{
if (timing == AutoTriggerTiming.OrderCreate
&& string.Equals(trigger.Operation?.Trim(), InterceptOperation, StringComparison.Ordinal))
{
continue;
}
if (!AutoTriggerConditionMatcher.Matches(context, trigger.TriggerCondition))
{
continue;
}
try
{
await ExecuteTriggerAsync(order, trigger, operatorUserId);
}
catch (Exception ex)
{
logger.LogWarning(ex, "自动触发失败 OrderId={OrderId} TriggerId={TriggerId}", order.Id, trigger.Id);
}
}
}
public async Task FireByOrderIdAsync(int orderId, AutoTriggerTiming timing, int operatorUserId)
{
var order = await orderRepository.FirstOrDefaultAsync(x => x.Id == orderId);
if (order == null)
{
return;
}
await FireAsync(order, timing, operatorUserId);
}
private async Task ExecuteTriggerAsync(
Order order,
AutoTrigger trigger,
int operatorUserId)
{
var operation = trigger.Operation?.Trim();
if (string.Equals(operation, InterceptOperation, StringComparison.Ordinal))
{
if (order.IsIntercept == 0)
{
order.IsIntercept = 1;
await orderRepository.UpdateAsync(order);
}
return;
}
if (string.Equals(operation, "警告", StringComparison.Ordinal))
{
var title = string.IsNullOrWhiteSpace(trigger.PromptMessage)
? "订单预警"
: trigger.PromptMessage.Trim();
var content = string.IsNullOrWhiteSpace(trigger.TriggerCondition)
? $"运单 {{serviceNo}} 触发自动警告规则"
: trigger.TriggerCondition.Trim();
var context = IssuePlaceholderContext.FromOrder(order, null, title);
await issueNotificationService.DispatchAsync(
order,
IssuePlaceholderRenderer.Render(title, context),
IssuePlaceholderRenderer.Render(content, context),
IssueNotifyMethodCodes.InApp,
operatorUserId,
null,
AutoTriggerConditionMatcher.ParseNotifierUserIds(trigger.Notifier));
return;
}
if (!string.Equals(operation, "问题件", StringComparison.Ordinal))
{
return;
}
var issueType = AutoTriggerConditionMatcher.ResolveIssueType(trigger.TriggerCondition);
var request = await exceptionWorkflowService.BuildRequestFromTemplateAsync(
order.OrganizationId,
issueType,
trigger.PromptMessage,
null,
$"自动触发#{trigger.Id}");
if (request == null)
{
logger.LogInformation(
"自动触发问题件跳过:未匹配问题模板 OrderId={OrderId} TriggerId={TriggerId}",
order.Id,
trigger.Id);
return;
}
request.ExtraReceiverUserIds = AutoTriggerConditionMatcher.ParseNotifierUserIds(trigger.Notifier);
var reason = await exceptionWorkflowService.TryMarkProblematicAsync(order, request, operatorUserId, true);
if (!string.IsNullOrWhiteSpace(reason))
{
logger.LogInformation(
"自动触发问题件未执行 OrderId={OrderId} TriggerId={TriggerId} Reason={Reason}",
order.Id,
trigger.Id,
reason);
}
}
}