修复工单Bug
This commit is contained in:
1 parent
7982f7e348
commit
8e0cc20649
12 files changed
+602
-236
No files matched your search
@@ -1,6 +1,5 @@
|
||||
using AllBase.Helper;
|
||||
using AllBase.Model.DBModel;
|
||||
using NaiBa.Util.Helper;
|
||||
using OrderSupportTicket.Models;
|
||||
using OrderSupportTicket.Models.Api;
|
||||
using OrderSupportTicket.Services;
|
||||
@@ -9,7 +8,6 @@ using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
@@ -32,9 +30,8 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
/// </summary>
|
||||
public const string OrderParameterKey = "order";
|
||||
|
||||
private const string SavedListConfigName = "ordersupportticket";
|
||||
private readonly ITicketApiService _api;
|
||||
private readonly ITicketRealtimeService _realtime;
|
||||
private readonly TicketService _ticketService;
|
||||
private readonly WorkOrderCacheService _cacheService = new WorkOrderCacheService();
|
||||
private readonly Dispatcher _dispatcher;
|
||||
private readonly AsyncDelegateCommand<WorkOrderSummaryViewModel> _selectTicketCommand;
|
||||
private readonly AsyncDelegateCommand _createTicketCommand;
|
||||
@@ -52,7 +49,6 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
private bool _configured;
|
||||
private bool _initialized;
|
||||
private bool _disposed;
|
||||
private readonly bool _ownsRealtime;
|
||||
private string _pendingOpenKey;
|
||||
private WorkOrderSummaryViewModel _selectedTicket;
|
||||
private TicketOrderOption _selectedOrder;
|
||||
@@ -82,14 +78,11 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
private int _selectionVersion;
|
||||
|
||||
public OrderSupportTicketViewModel(
|
||||
ITicketApiService api,
|
||||
ITicketRealtimeService realtime,
|
||||
TicketClientOptions options = null,
|
||||
bool ownsRealtime = true)
|
||||
TicketService ticketService,
|
||||
TicketClientOptions options = null)
|
||||
{
|
||||
_api = api ?? throw new ArgumentNullException(nameof(api));
|
||||
_realtime = realtime ?? throw new ArgumentNullException(nameof(realtime));
|
||||
_ownsRealtime = ownsRealtime;
|
||||
_ticketService = ticketService
|
||||
?? throw new ArgumentNullException(nameof(ticketService));
|
||||
_dispatcher = System.Windows.Application.Current?.Dispatcher
|
||||
?? Dispatcher.CurrentDispatcher;
|
||||
|
||||
@@ -112,10 +105,10 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
_retryRealtimeCommand = new AsyncDelegateCommand(
|
||||
RestartRealtimeAsync,
|
||||
() => !IsBusy && _configured);
|
||||
_realtime.NotificationReceived += OnNotificationReceived;
|
||||
_realtime.StateChanged += OnRealtimeStateChanged;
|
||||
SseState = TicketRealtimeState.Disconnected;
|
||||
SseStatusText = "实时推送:未连接";
|
||||
_ticketService.NotificationReceived += OnNotificationReceived;
|
||||
_ticketService.StateChanged += OnRealtimeStateChanged;
|
||||
SseState = _ticketService.RealtimeState;
|
||||
SseStatusText = GetRealtimeStatusText(SseState);
|
||||
|
||||
if (options != null)
|
||||
Configure(options);
|
||||
@@ -636,17 +629,16 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException(nameof(OrderSupportTicketViewModel));
|
||||
|
||||
if (_ownsRealtime)
|
||||
if (_ticketService.OwnsRealtime)
|
||||
{
|
||||
_ = _realtime.StopAsync();
|
||||
_ = _ticketService.StopRealtimeAsync();
|
||||
SseState = TicketRealtimeState.Disconnected;
|
||||
SseStatusText = GetRealtimeStatusText(SseState);
|
||||
}
|
||||
else
|
||||
{
|
||||
SseState = _realtime.State;
|
||||
SseStatusText = GetRealtimeStatusText(SseState);
|
||||
SseState = _ticketService.RealtimeState;
|
||||
}
|
||||
SseStatusText = GetRealtimeStatusText(SseState);
|
||||
_configured = false;
|
||||
_initialized = false;
|
||||
_pendingOpenKey = null;
|
||||
@@ -680,7 +672,7 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
{
|
||||
try
|
||||
{
|
||||
TicketApiService.ValidateOptions(_options);
|
||||
_ticketService.ValidateOptions(_options);
|
||||
if (_options.AppIds == null || _options.AppIds.Count == 0)
|
||||
throw new ArgumentException("appIds 至少需要一个 APPID。");
|
||||
_configured = true;
|
||||
@@ -718,11 +710,11 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
var started = false;
|
||||
// 共享连接由宿主统一维护,页面首次打开时不能因为 _initialized=false 重启连接。
|
||||
var shouldStartRealtime =
|
||||
_realtime.State == TicketRealtimeState.Disconnected
|
||||
|| (_ownsRealtime && !_initialized);
|
||||
_ticketService.RealtimeState == TicketRealtimeState.Disconnected
|
||||
|| (_ticketService.OwnsRealtime && !_initialized);
|
||||
if (shouldStartRealtime)
|
||||
{
|
||||
_realtime.Start(_options);
|
||||
_ticketService.StartRealtime(_options);
|
||||
started = true;
|
||||
}
|
||||
|
||||
@@ -743,8 +735,8 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
public async Task DeactivateAsync()
|
||||
{
|
||||
SaveWorkOrderList();
|
||||
if (_ownsRealtime)
|
||||
await _realtime.StopAsync();
|
||||
if (_ticketService.OwnsRealtime)
|
||||
await _ticketService.StopRealtimeAsync();
|
||||
}
|
||||
|
||||
public void OpenNewTicket(TicketOrderOption order)
|
||||
@@ -834,10 +826,9 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
return;
|
||||
SaveWorkOrderList();
|
||||
_disposed = true;
|
||||
_realtime.NotificationReceived -= OnNotificationReceived;
|
||||
_realtime.StateChanged -= OnRealtimeStateChanged;
|
||||
if (_ownsRealtime)
|
||||
_realtime.Dispose();
|
||||
_ticketService.NotificationReceived -= OnNotificationReceived;
|
||||
_ticketService.StateChanged -= OnRealtimeStateChanged;
|
||||
_ticketService.Dispose();
|
||||
}
|
||||
|
||||
private void OpenNewDraft()
|
||||
@@ -938,7 +929,7 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
ClearNotice();
|
||||
try
|
||||
{
|
||||
var result = await _api.CreateWorkOrderAsync(
|
||||
var result = await _ticketService.CreateWorkOrderAsync(
|
||||
_options,
|
||||
SelectedOrder,
|
||||
description,
|
||||
@@ -1010,7 +1001,7 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
ClearNotice();
|
||||
try
|
||||
{
|
||||
var result = await _api.SendMessageAsync(
|
||||
var result = await _ticketService.SendMessageAsync(
|
||||
_options,
|
||||
ToSummaryDto(ticket),
|
||||
text,
|
||||
@@ -1068,7 +1059,7 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
IsBusy = true;
|
||||
try
|
||||
{
|
||||
var response = await _api.GetMessagesAsync(
|
||||
var response = await _ticketService.GetMessagesAsync(
|
||||
_options,
|
||||
ticket.AppId,
|
||||
ticket.WechatOrderId,
|
||||
@@ -1096,8 +1087,7 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
IsBusy = true;
|
||||
try
|
||||
{
|
||||
await _realtime.StopAsync();
|
||||
_realtime.Start(_options);
|
||||
await _ticketService.RestartRealtimeAsync(_options);
|
||||
await RefreshAllWorkOrdersAsync(loadSelectedMessages: false);
|
||||
if (SelectedTicket != null && !IsDraft)
|
||||
await LoadMessagesAsync(SelectedTicket, replace: true);
|
||||
@@ -1121,7 +1111,7 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
IsLoadingMessages = true;
|
||||
try
|
||||
{
|
||||
var response = await _api.GetMessagesAsync(
|
||||
var response = await _ticketService.GetMessagesAsync(
|
||||
_options,
|
||||
ticket.AppId,
|
||||
ticket.WechatOrderId,
|
||||
@@ -1168,7 +1158,7 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
var page = 0;
|
||||
do
|
||||
{
|
||||
var response = await _api.GetWorkOrdersAsync(
|
||||
var response = await _ticketService.GetWorkOrdersAsync(
|
||||
_options,
|
||||
limit: 100,
|
||||
cursor: cursor);
|
||||
@@ -1240,7 +1230,7 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
|
||||
var options = CloneOptions(_options);
|
||||
options.AppIds = new List<string> { appId };
|
||||
var response = await _api.GetWorkOrdersAsync(
|
||||
var response = await _ticketService.GetWorkOrdersAsync(
|
||||
options,
|
||||
wechatOrderId,
|
||||
limit: 1);
|
||||
@@ -1338,7 +1328,7 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
|
||||
try
|
||||
{
|
||||
await _api.MarkReadAsync(
|
||||
await _ticketService.MarkReadAsync(
|
||||
_options,
|
||||
ticket.AppId,
|
||||
ticket.WechatOrderId,
|
||||
@@ -1671,21 +1661,8 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
if (string.IsNullOrWhiteSpace(_options?.UserName))
|
||||
return;
|
||||
|
||||
if (!File.Exists(ConfigHelper.GetConfigUserPath(SavedListConfigName)))
|
||||
return;
|
||||
|
||||
WorkOrderListCache cache;
|
||||
try
|
||||
{
|
||||
cache = ConfigHelper.LoadConfig<WorkOrderListCache>(SavedListConfigName);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (cache?.Items == null
|
||||
|| !string.Equals(cache.UserName, _options.UserName, StringComparison.Ordinal))
|
||||
var cache = _cacheService.Load(_options.UserName);
|
||||
if (cache?.Items == null)
|
||||
return;
|
||||
|
||||
foreach (var saved in cache.Items)
|
||||
@@ -1735,7 +1712,7 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
|
||||
try
|
||||
{
|
||||
ConfigHelper.SaveConfig(SavedListConfigName, cache);
|
||||
_cacheService.Save(cache);
|
||||
_hasSavedCache = true;
|
||||
}
|
||||
catch
|
||||
@@ -1751,7 +1728,8 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
if (!_savedWorkOrders.TryGetValue(dto.WechatOrderId, out var saved))
|
||||
return _hasSavedCache;
|
||||
|
||||
return ParseTimestamp(dto.LastMessageAt) > saved.LastMessageAt;
|
||||
return WorkOrderCacheService.ParseTimestamp(dto.LastMessageAt)
|
||||
> saved.LastMessageAt;
|
||||
}
|
||||
|
||||
private static WorkOrderListCacheItem ToCacheItem(
|
||||
@@ -1767,18 +1745,6 @@ public sealed class OrderSupportTicketViewModel : BindableBaseEx, IDialogAware,
|
||||
};
|
||||
}
|
||||
|
||||
private static DateTimeOffset ParseTimestamp(string value)
|
||||
{
|
||||
if (DateTimeOffset.TryParse(
|
||||
value,
|
||||
CultureInfo.InvariantCulture,
|
||||
DateTimeStyles.AssumeUniversal,
|
||||
out var parsed))
|
||||
{
|
||||
return parsed;
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
private static string NewOperationId(string prefix)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user