Files
FATrace/FATrace.WPLApp/ViewModels/FactoryInboundViewModel.cs
2026-01-13 15:03:02 +08:00

223 lines
8.3 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 FATrace.WPLApp.Core;
using Prism.Commands;
using System;
using System.Collections.ObjectModel;
using FreeSql;
using FATrace.Model;
using FATrace.WPLApp.Services;
using System.Threading.Tasks;
using System.Windows;
namespace FATrace.WPLApp.ViewModels
{
/// <summary>
/// 工厂-入库 数据查询 VM
/// 仅展示从 Excel 导入的 FactoryInbound 数据,支持简单条件与分页。
/// </summary>
public class FactoryInboundViewModel : NavigationViewModel
{
private readonly IFreeSql _fsql;
private readonly ILogService _log;
public FactoryInboundViewModel(IFreeSql fsql, ILogService log)
{
_fsql = fsql;
_log = log;
Items = new ObservableCollection<FactoryInbound>();
SearchCommand = new DelegateCommand(async () => await SearchAsync(), () => !IsBusy)
.ObservesProperty(() => IsBusy);
ClearCommand = new DelegateCommand(ClearFilters, () => !IsBusy)
.ObservesProperty(() => IsBusy);
FirstPageCommand = new DelegateCommand(async () => { if (PageIndex == 1) return; PageIndex = 1; await SearchAsync(); }, () => !IsBusy && PageIndex > 1)
.ObservesProperty(() => IsBusy)
.ObservesProperty(() => PageIndex);
PrevPageCommand = new DelegateCommand(async () => { if (PageIndex <= 1) return; PageIndex -= 1; await SearchAsync(); }, () => !IsBusy && PageIndex > 1)
.ObservesProperty(() => IsBusy)
.ObservesProperty(() => PageIndex);
NextPageCommand = new DelegateCommand(async () => { if (PageIndex >= TotalPages) return; PageIndex += 1; await SearchAsync(); }, () => !IsBusy && PageIndex < TotalPages)
.ObservesProperty(() => IsBusy)
.ObservesProperty(() => PageIndex)
.ObservesProperty(() => TotalPages);
LastPageCommand = new DelegateCommand(async () => { if (TotalPages <= 0 || PageIndex == TotalPages) return; PageIndex = TotalPages; await SearchAsync(); }, () => !IsBusy && PageIndex < TotalPages)
.ObservesProperty(() => IsBusy)
.ObservesProperty(() => PageIndex)
.ObservesProperty(() => TotalPages);
}
#region
private string? _origin;
/// <summary>
/// 产地模糊匹配
/// </summary>
public string? Origin { get => _origin; set { _origin = value; RaisePropertyChanged(); } }
private string? _rawCode;
/// <summary>
/// 原料代码模糊匹配
/// </summary>
public string? RawCode { get => _rawCode; set { _rawCode = value; RaisePropertyChanged(); } }
private string? _rawName;
/// <summary>
/// 原料名称模糊匹配
/// </summary>
public string? RawName { get => _rawName; set { _rawName = value; RaisePropertyChanged(); } }
private DateTime? _startDate;
/// <summary>
/// 登录日期起(根据 LoginDateTime 转换为日期范围过滤)
/// </summary>
public DateTime? StartDate
{
get => _startDate;
set { _startDate = value; RaisePropertyChanged(); }
}
private DateTime? _endDate;
/// <summary>
/// 登录日期止(包含当天,基于 LoginDateTime
/// </summary>
public DateTime? EndDate
{
get => _endDate;
set { _endDate = value; RaisePropertyChanged(); }
}
#endregion
#region
public ObservableCollection<FactoryInbound> Items { get; }
private bool _isBusy;
public bool IsBusy { get => _isBusy; set { _isBusy = value; RaisePropertyChanged(); } }
private int _totalCount;
public int TotalCount { get => _totalCount; set { _totalCount = value; RaisePropertyChanged(); } }
private int _pageIndex = 1;
public int PageIndex
{
get => _pageIndex;
set { _pageIndex = value < 1 ? 1 : value; RaisePropertyChanged(); }
}
private int _pageSize = 20;
public int PageSize
{
get => _pageSize;
set
{
var v = value <= 0 ? 20 : value;
if (_pageSize != v)
{
_pageSize = v;
RaisePropertyChanged();
PageIndex = 1;
if (!IsBusy) _ = SearchAsync();
}
}
}
private int _totalPages;
public int TotalPages { get => _totalPages; set { _totalPages = value; RaisePropertyChanged(); } }
#endregion
#region
public DelegateCommand SearchCommand { get; }
public DelegateCommand ClearCommand { get; }
public DelegateCommand FirstPageCommand { get; }
public DelegateCommand PrevPageCommand { get; }
public DelegateCommand NextPageCommand { get; }
public DelegateCommand LastPageCommand { get; }
#endregion
private void ClearFilters()
{
Origin = RawCode = RawName = string.Empty;
StartDate = null;
EndDate = null;
}
private async Task SearchAsync()
{
if (IsBusy) return;
try
{
IsBusy = true;
_log.Info("FactoryInbound 查询开始");
var data = await Task.Run(() =>
{
var q = _fsql.Select<FactoryInbound>();
if (!string.IsNullOrWhiteSpace(Origin))
q = q.Where(a => a.Origin != null && a.Origin.Contains(Origin));
if (!string.IsNullOrWhiteSpace(RawCode))
q = q.Where(a => a.RawCode != null && a.RawCode.Contains(RawCode));
if (!string.IsNullOrWhiteSpace(RawName))
q = q.Where(a => a.RawName != null && a.RawName.Contains(RawName));
// 日期范围:基于 LoginDateTime 进行 TRY_CONVERT(datetime, LoginDateTime) 比较
DateTime? start = StartDate;
DateTime? end = EndDate;
if (start.HasValue)
{
var s = start.Value.Date;
q = q.Where("TRY_CONVERT(datetime, LoginDateTime) >= @start", new { start = s });
}
if (end.HasValue)
{
var e = end.Value.Date.AddDays(1).AddTicks(-1);
q = q.Where("TRY_CONVERT(datetime, LoginDateTime) <= @end", new { end = e });
}
q = q.OrderByDescending(a => a.Id);
var page = PageIndex < 1 ? 1 : PageIndex;
var size = PageSize <= 0 ? 20 : PageSize;
var list = q.Count(out var total)
.Page(page, size)
.ToList();
var pages = total <= 0 || size <= 0 ? 0 : (int)Math.Ceiling(total * 1.0 / size);
if (pages > 0 && page > pages)
{
page = pages;
list = q.Page(page, size).ToList();
}
return (items: list, total: (int)total, normalizedPage: page, totalPages: pages);
});
Application.Current.Dispatcher.Invoke(() =>
{
Items.Clear();
foreach (var it in data.items) Items.Add(it);
TotalCount = data.total;
TotalPages = data.totalPages;
PageIndex = data.normalizedPage == 0 ? 1 : data.normalizedPage;
});
_log.Info($"FactoryInbound 查询完成,记录数: {TotalCount}");
}
catch (Exception ex)
{
_log.Error($"FactoryInbound 查询失败: {ex}");
MessageBox.Show($"查询失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
finally
{
IsBusy = false;
}
}
public override async void OnNavigatedTo(Prism.Regions.NavigationContext navigationContext)
{
await SearchAsync();
}
}
}