feat: 添加订单超时提醒功能

- 订单同步入库后超过48小时未发货自动弹出警告
- 显示超时订单详情(订单号、收件人、等待时长)
- 播放系统警告音、任务栏闪烁
- 关闭提醒后每小时重复提醒,直到订单发货

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Administrator
2025-12-18 00:54:01 +08:00
parent 92b38fc656
commit a1208eeaca

View File

@@ -22,7 +22,11 @@ namespace PackagingMallShipper.ViewModels
private readonly IExcelService _excelService;
private DispatcherTimer _autoSyncTimer;
private DispatcherTimer _overdueCheckTimer;
private DateTime? _lastOverdueAlertTime;
private const int AutoSyncIntervalMinutes = 30;
private const int OverdueHours = 48; // 超时阈值(小时)
private const int OverdueAlertIntervalMinutes = 60; // 超时提醒间隔(分钟)
[ObservableProperty]
private ObservableCollection<Order> _orders = new ObservableCollection<Order>();
@@ -82,6 +86,9 @@ namespace PackagingMallShipper.ViewModels
// 初始化自动同步定时器
InitializeAutoSyncTimer();
// 初始化超时检查定时器
InitializeOverdueCheckTimer();
}
private void InitializeAutoSyncTimer()
@@ -101,6 +108,16 @@ namespace PackagingMallShipper.ViewModels
updateTimer.Start();
}
private void InitializeOverdueCheckTimer()
{
// 每10分钟检查一次超时订单
_overdueCheckTimer = new DispatcherTimer
{
Interval = TimeSpan.FromMinutes(10)
};
_overdueCheckTimer.Tick += async (s, e) => await CheckOverdueOrdersAsync();
}
public async Task InitializeAsync()
{
await RefreshOrdersAsync();
@@ -108,6 +125,11 @@ namespace PackagingMallShipper.ViewModels
// 启动自动同步
StartAutoSync();
// 启动超时检查延迟5秒后开始给界面加载时间
_overdueCheckTimer?.Start();
await Task.Delay(5000);
await CheckOverdueOrdersAsync();
}
public void StartAutoSync()
@@ -320,6 +342,82 @@ namespace PackagingMallShipper.ViewModels
public uint dwTimeout;
}
private async Task CheckOverdueOrdersAsync()
{
try
{
// 检查是否需要提醒距离上次提醒超过1小时
if (_lastOverdueAlertTime.HasValue &&
(DateTime.Now - _lastOverdueAlertTime.Value).TotalMinutes < OverdueAlertIntervalMinutes)
{
return;
}
// 获取所有待发货订单
var pendingOrders = await _orderService.GetOrdersAsync(1, null);
var now = DateTime.Now;
// 筛选超过48小时未发货的订单基于同步入库时间 SyncedAt
var overdueOrders = pendingOrders
.Where(o => o.SyncedAt.HasValue &&
(now - o.SyncedAt.Value).TotalHours >= OverdueHours)
.OrderBy(o => o.SyncedAt)
.ToList();
if (overdueOrders.Any())
{
_lastOverdueAlertTime = DateTime.Now;
ShowOverdueOrdersAlert(overdueOrders);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"检查超时订单失败: {ex.Message}");
}
}
private void ShowOverdueOrdersAlert(System.Collections.Generic.List<Order> overdueOrders)
{
Application.Current.Dispatcher.Invoke(() =>
{
// 播放警告提示音
System.Media.SystemSounds.Hand.Play();
// 构建提醒消息
var message = $"⚠️ 发现 {overdueOrders.Count} 个订单超过 {OverdueHours} 小时未发货!\n\n";
// 显示前5个超时订单的详情
var displayOrders = overdueOrders.Take(5).ToList();
foreach (var order in displayOrders)
{
var hours = order.SyncedAt.HasValue
? (int)(DateTime.Now - order.SyncedAt.Value).TotalHours
: 0;
message += $"• {order.OrderNumber} - {order.LogisticsName} - 已等待 {hours} 小时\n";
}
if (overdueOrders.Count > 5)
{
message += $"\n...还有 {overdueOrders.Count - 5} 个超时订单\n";
}
message += $"\n请尽快处理\n此提醒每小时弹出一次直到所有订单发货";
// 闪烁任务栏
var mainWindow = Application.Current.MainWindow;
if (mainWindow != null)
{
FlashWindow(mainWindow);
}
// 显示警告对话框
MessageBox.Show(message, "⚠️ 订单超时提醒", MessageBoxButton.OK, MessageBoxImage.Warning);
// 更新状态栏
StatusMessage = $"⚠️ {overdueOrders.Count} 个订单超时未发货!";
});
}
partial void OnAutoSyncEnabledChanged(bool value)
{
if (value)
@@ -560,6 +658,7 @@ namespace PackagingMallShipper.ViewModels
public void Cleanup()
{
_autoSyncTimer?.Stop();
_overdueCheckTimer?.Stop();
}
}
}