|
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
|
|
using CommunityToolkit.Mvvm.Input;
|
|
|
|
using IndustrialControl.Services;
|
|
|
|
using IndustrialControl.Pages;
|
|
|
|
using System.Collections.ObjectModel;
|
|
|
|
|
|
|
|
namespace IndustrialControl.ViewModels;
|
|
|
|
|
|
|
|
public partial class BinPickerViewModel : ObservableObject
|
|
|
|
{
|
|
|
|
public ObservableCollection<BinTreeNode> Tree { get; } = new();
|
|
|
|
public ObservableCollection<BinInfo> AllBins { get; } = new();
|
|
|
|
public ObservableCollection<BinTreeNode> VisibleTree { get; } = new();
|
|
|
|
|
|
|
|
private Func<BinInfo, Task>? _onPicked;
|
|
|
|
private Func<Task>? _onCanceled;
|
|
|
|
|
|
|
|
public void SetCloseHandlers(Func<BinInfo, Task> onPicked, Func<Task> onCanceled)
|
|
|
|
{
|
|
|
|
_onPicked = onPicked;
|
|
|
|
_onCanceled = onCanceled;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Initialize(string? preselectBinCode)
|
|
|
|
{
|
|
|
|
BuildMockTree();
|
|
|
|
BuildMockBins();
|
|
|
|
// 根/区域默认展开,这样有下级
|
|
|
|
foreach (var root in Tree) root.IsExpanded = true;
|
|
|
|
RebuildVisible(); // ★ 初始化可见列表
|
|
|
|
}
|
|
|
|
|
|
|
|
// 展开/收起
|
|
|
|
[RelayCommand]
|
|
|
|
private void Toggle(BinTreeNode node)
|
|
|
|
{
|
|
|
|
node.IsExpanded = !node.IsExpanded;
|
|
|
|
RebuildVisible(); // ★ 每次切换都重建
|
|
|
|
}
|
|
|
|
|
|
|
|
// 选中树节点:Level==2 表示“货架” → 弹出库位列表;否则仅展开
|
|
|
|
[RelayCommand]
|
|
|
|
private async Task SelectNode(BinTreeNode node)
|
|
|
|
{
|
|
|
|
if (node.Level != 2)
|
|
|
|
{
|
|
|
|
node.IsExpanded = !node.IsExpanded;
|
|
|
|
RebuildVisible();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var list = AllBins.Where(b => b.ShelfPath.Equals(node.Path, StringComparison.OrdinalIgnoreCase)).ToList();
|
|
|
|
|
|
|
|
// ★ 让 BinListPage 在选择后连关自己和父页
|
|
|
|
var picked = await BinListPage.ShowAsync(list, closeParent: true);
|
|
|
|
if (picked == null) return;
|
|
|
|
|
|
|
|
// 仍把结果回传,完成 BinPickerPage.ShowAsync 的 Task
|
|
|
|
if (_onPicked != null)
|
|
|
|
await _onPicked.Invoke(picked);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ★ 递归把“当前应可见”的节点平铺出来
|
|
|
|
private void RebuildVisible()
|
|
|
|
{
|
|
|
|
VisibleTree.Clear();
|
|
|
|
foreach (var root in Tree)
|
|
|
|
AddVisible(root);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void AddVisible(BinTreeNode n)
|
|
|
|
{
|
|
|
|
VisibleTree.Add(n);
|
|
|
|
if (!n.IsExpanded) return;
|
|
|
|
foreach (var c in n.Children)
|
|
|
|
AddVisible(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Task CancelAsync() => _onCanceled?.Invoke() ?? Task.CompletedTask;
|
|
|
|
|
|
|
|
// ====== Mock(保持不变,只展示必要部分)======
|
|
|
|
private void BuildMockTree()
|
|
|
|
{
|
|
|
|
Tree.Clear();
|
|
|
|
var semi = new BinTreeNode("半成品库", 0, "半成品库") { IsExpanded = true };
|
|
|
|
var semiAreaA = new BinTreeNode("区域A", 1, "半成品库/区域A") { IsExpanded = true };
|
|
|
|
semiAreaA.Children.Add(new BinTreeNode("货架A1", 2, "半成品库/区域A/货架A1"));
|
|
|
|
semi.Children.Add(semiAreaA);
|
|
|
|
Tree.Add(semi);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void BuildMockBins()
|
|
|
|
{
|
|
|
|
AllBins.Clear();
|
|
|
|
AllBins.Add(new BinInfo
|
|
|
|
{
|
|
|
|
BinCode = "A1-101",
|
|
|
|
WarehouseName = "半成品库",
|
|
|
|
WarehouseCode = "FBCPK",
|
|
|
|
Layer = "货架层A1-1",
|
|
|
|
Shelf = "货架A1",
|
|
|
|
Zone = "区域A",
|
|
|
|
Status = "-",
|
|
|
|
ShelfPath = "半成品库/区域A/货架A1"
|
|
|
|
});
|
|
|
|
AllBins.Add(new BinInfo
|
|
|
|
{
|
|
|
|
BinCode = "A1-102",
|
|
|
|
WarehouseName = "半成品库",
|
|
|
|
WarehouseCode = "FBCPK",
|
|
|
|
Layer = "货架层A1-1",
|
|
|
|
Shelf = "货架A1",
|
|
|
|
Zone = "区域A",
|
|
|
|
Status = "-",
|
|
|
|
ShelfPath = "半成品库/区域A/货架A1"
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 树节点
|
|
|
|
public partial class BinTreeNode : ObservableObject
|
|
|
|
{
|
|
|
|
public BinTreeNode(string name, int level, string path)
|
|
|
|
{ Name = name; Level = level; Path = path; Indent = new Thickness(level * 16, 0, 0, 0); }
|
|
|
|
|
|
|
|
[ObservableProperty] private string name;
|
|
|
|
[ObservableProperty] private bool isExpanded;
|
|
|
|
public int Level { get; }
|
|
|
|
public string Path { get; }
|
|
|
|
public Thickness Indent { get; }
|
|
|
|
public ObservableCollection<BinTreeNode> Children { get; } = new();
|
|
|
|
public string ToggleIcon => Children.Count == 0 ? "" : (IsExpanded ? "▾" : "▸");
|
|
|
|
} |
...
|
...
|
|