using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Sln.Wcs.Repository.service.@base; using Sln.Wcs.UI.Views.Base; namespace Sln.Wcs.UI.ViewModels.Base; public interface ICrudPageViewModel { void Load(); Avalonia.Controls.Control CreateView(); string PageTitle { get; } } public abstract partial class CrudPageViewModel : ObservableObject, ICrudPageViewModel where T : class, new() { protected readonly IBaseService _service; [ObservableProperty] private ObservableCollection _items = new(); [ObservableProperty] private T? _selectedItem; [ObservableProperty] private string _searchText = string.Empty; [ObservableProperty] private string _pageTitle = string.Empty; [ObservableProperty] private string _statusText = string.Empty; public abstract List FieldConfigs { get; } public abstract Avalonia.Controls.Control CreateView(); /// /// Expression to search by name/code field. Override to customize. /// Returns null to skip filtering (load all). /// protected abstract Expression>? BuildSearchExpression(string search); protected CrudPageViewModel(IBaseService service) { _service = service; AddCommand = new AsyncRelayCommand(Add); EditCommand = new AsyncRelayCommand(Edit); } [RelayCommand] public void Load() { try { List list; if (string.IsNullOrWhiteSpace(SearchText)) { list = _service.Query(); } else { var exp = BuildSearchExpression(SearchText); list = exp != null ? _service.Query(exp) : _service.Query(); } Items = new ObservableCollection(list); StatusText = $"共 {list.Count} 条记录"; } catch (Exception ex) { StatusText = $"加载失败: {ex.Message}"; } } public AsyncRelayCommand AddCommand { get; } public AsyncRelayCommand EditCommand { get; } private async System.Threading.Tasks.Task Add() { var entity = new T(); var editor = new EntityEditWindow(); var result = await editor.ShowDialog(entity, FieldConfigs, false, GetMainWindow()); if (result) { _service.Insert(entity); Load(); StatusText = "新增成功"; } } private async System.Threading.Tasks.Task Edit() { if (SelectedItem is null) return; var editor = new EntityEditWindow(); var result = await editor.ShowDialog(SelectedItem, FieldConfigs, true, GetMainWindow()); if (result) { _service.Update(SelectedItem); Load(); StatusText = "编辑成功"; } } [RelayCommand] private void Delete() { if (SelectedItem is null) return; var prop = typeof(T).GetProperty("objId") ?? typeof(T).GetProperty("ObjId"); if (prop is null) return; var id = prop.GetValue(SelectedItem); _service.DeleteById(id!); Load(); StatusText = "删除成功"; } [RelayCommand] private void Search() { Load(); } private Avalonia.Controls.Window GetMainWindow() { return (Avalonia.Controls.Window)Avalonia.Application.Current! .ApplicationLifetime!.GetType() .GetProperty("MainWindow")! .GetValue(Avalonia.Application.Current.ApplicationLifetime)!; } }