using Fake.Application; using Newtonsoft.Json; using Oms.Application.Dtos.Orders; using Oms.Application.Labeling; using Oms.Application.Services.Orders.Issues; using Oms.Domain.OrdersAggregate.Consts; using Oms.Domain.OrdersAggregate.Entities; namespace Oms.Application.Services.Orders; public partial class OrderService { internal Task PayForBatchAsync(int orderId, CancellationToken cancellationToken = default) => PayAsync(new OrderActionInput { Id = orderId }); internal Task PreDeclareForBatchAsync(int orderId, CancellationToken cancellationToken = default) => PreDeclareAsync(new OrderActionInput { Id = orderId }); internal Task InterceptForBatchAsync(int orderId, CancellationToken cancellationToken = default) => InterceptAsync(new OrderActionInput { Id = orderId }); internal Task CancelInterceptForBatchAsync(int orderId, CancellationToken cancellationToken = default) => CancelInterceptAsync(new OrderActionInput { Id = orderId }); internal Task DeleteForBatchAsync(int orderId, CancellationToken cancellationToken = default) => DeleteAsync(new OrderActionInput { Id = orderId }); internal Task PrintForBatchAsync(int orderId, CancellationToken cancellationToken = default) => PrintAsync(new OrderActionInput { Id = orderId }); internal async Task GenerateLabelPdfForBatchAsync( int orderId, CancellationToken cancellationToken = default) { var order = await GetOrderOrThrowAsync(orderId); var mapped = (await MapOrderOutputsAsync([order])).First(); return await LabelPdfGenerationService.GenerateAndPersistAsync( order, mapped, templateIdOverride: null, operatorName: null, operatorUserId: 0, cancellationToken); } internal async Task MarkProblematicForBatchAsync( int orderId, string? payloadJson, int operatorUserId, CancellationToken cancellationToken = default) { var input = DeserializeBatchPayload(payloadJson) ?? throw new BusinessException("问题件参数无效"); input.OrderIds = [orderId]; var payload = await ResolveProblematicPayloadAsync(input); var request = new ProblematicMarkRequest { IssueType = payload.IssueType, Title = payload.Title, Content = payload.Content, IssueTemplateId = payload.IssueTemplateId, NotifyMethod = payload.NotifyMethod, Remark = payload.Remark, }; var order = await GetOrderOrThrowAsync(orderId); var sendNotification = !string.IsNullOrWhiteSpace(request.NotifyMethod); var reason = await ExceptionWorkflowService.TryMarkProblematicAsync( order, request, operatorUserId, sendNotification); if (!string.IsNullOrWhiteSpace(reason)) { throw new BusinessException(reason); } } internal async Task MarkClaimedForBatchAsync( int orderId, string? payloadJson, CancellationToken cancellationToken = default) { var input = DeserializeBatchPayload(payloadJson) ?? throw new BusinessException("理赔件参数无效"); var payload = NormalizeClaimedPayload(input); var order = await GetOrderOrThrowAsync(orderId); if (!OrderExceptionStatusRules.CanMarkException(order.OrderStatus)) { throw new BusinessException(OrderExceptionStatusRules.GetForbiddenReason(order.OrderStatus)); } var fromStatus = order.OrderStatus; order.PreviousOrderStatus = fromStatus; order.OrderStatus = OrderStatusCodes.Claimed; order.HandleStatus = OrderHandleStatusCodes.Pending; order.ClaimType = payload.ClaimType; order.ClaimAmount = payload.ClaimAmount; order.ClaimCurrency = payload.ClaimCurrency; order.ClaimReason = payload.ClaimReason; order.ClaimTime = DateTime.Now; order.IssueType = null; order.IssueTitle = null; order.IssueContent = null; order.IssueTemplateId = null; order.IssueRemark = null; order.IssueTime = null; await OrderRepository.UpdateAsync(order); await OrderExceptionEventRepository.InsertAsync(new OrderExceptionEvent { OrderId = order.Id, EventType = OrderExceptionEventTypeCodes.MarkClaimed, FromStatus = fromStatus, ToStatus = OrderStatusCodes.Claimed, FromHandleStatus = null, ToHandleStatus = OrderHandleStatusCodes.Pending, ClaimType = payload.ClaimType, ClaimAmount = payload.ClaimAmount, ClaimCurrency = payload.ClaimCurrency, ClaimReason = payload.ClaimReason, Remark = payload.Remark, }); } internal async Task UpdateHandleStatusForBatchAsync( int orderId, string? payloadJson, CancellationToken cancellationToken = default) { var input = DeserializeBatchPayload(payloadJson) ?? throw new BusinessException("处理状态参数无效"); var targetStatus = input.HandleStatus?.Trim().ToLowerInvariant(); if (!string.Equals(targetStatus, OrderHandleStatusCodes.Processed, StringComparison.Ordinal)) { throw new BusinessException("仅支持标记为已处理"); } var order = await GetOrderOrThrowAsync(orderId); if (order.OrderStatus is not (OrderStatusCodes.Problematic or OrderStatusCodes.Claimed)) { throw new BusinessException("仅问题件或理赔件可更新处理状态"); } if (OrderHandleStatusCodes.IsProcessed(order.HandleStatus)) { throw new BusinessException("订单已处理"); } order.HandleStatus = OrderHandleStatusCodes.Processed; await OrderRepository.UpdateAsync(order); await OrderExceptionEventRepository.InsertAsync(new OrderExceptionEvent { OrderId = order.Id, EventType = OrderExceptionEventTypeCodes.HandleProcessed, FromStatus = order.OrderStatus, ToStatus = order.OrderStatus, FromHandleStatus = OrderHandleStatusCodes.Pending, ToHandleStatus = OrderHandleStatusCodes.Processed, Remark = input.Remark?.Trim(), }); } private static T? DeserializeBatchPayload(string? payloadJson) where T : class { if (string.IsNullOrWhiteSpace(payloadJson)) { return null; } return JsonConvert.DeserializeObject(payloadJson); } }