Files
SzmediTools/Szmedi.RvKits/InfoManager/EAMTools/EAMCodeCheckViewModel.cs
2025-09-16 16:06:41 +08:00

228 lines
8.0 KiB
C#

using System;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Windows;
using Autodesk.Revit.DB;
using EPPlus.Core.Extensions;
using EPPlus.Core.Extensions.Attributes;
using Nice3point.Revit.Toolkit.External.Handlers;
using OfficeOpenXml;
using Szmedi.RvKits.InfoManager.EAMTools;
namespace Szmedi.RvKits.InfoManager
{
public partial class EAMCodeCheckViewModel : ObservableObject
{
private readonly ActionEventHandler handler;
[ObservableProperty]
private List<EAMData> currentFacilities;
[ObservableProperty]
private List<InstanceFacility> instances;
[ObservableProperty]
private string selectedStation;
[ObservableProperty]
private List<string> facilitySystems;
[ObservableProperty]
private string selectedSystem;
public EAMCodeCheckViewModel(Document doc)
{
handler = new ActionEventHandler();
FileInfo fi = new(Path.Combine(GlobalVariables.DirAssembly, "Data", "EAM数据.xlsx"));
using ExcelPackage package = new(fi);
//ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainOnAssemblyResolve;
try
{
var list = doc.OfClass<FamilyInstance>()
.Where(
e => e.Category.AllowsBoundParameters &&
e.Category.CategoryType == CategoryType.Model &&
!Enum.GetName(typeof(BuiltInCategory), e.Category.Id.IntegerValue)!.Contains("Fitting") &&
e.Category.CategoryType == CategoryType.Model &&
e.Category.Id.IntegerValue != -2008013) //风道末端
.Cast<FamilyInstance>()
.OrderBy(ins => ins.Name)
.Select(ins => new InstanceFacility(ins));
Instances = [.. list];
Facilities = package.ToList<EAMData>(1, configuration => configuration.SkipCastingErrors());
var group = Facilities.GroupBy(fa => fa.StationName).OrderBy(g => g.Key);
Stations = [.. group.Select(g => g.Key)];
Regex regex = new Regex(@"-(\D+站|所|段|场)-");
var result = regex.Matches(doc.PathName).Cast<Match>().Select(m => m.Groups[1].Value).FirstOrDefault();
if (result != null && Stations.Contains(result))
{
SelectedStation = result;
}
}
catch (EPPlus.Core.Extensions.Exceptions.ExcelValidationException)
{
System.Windows.MessageBox.Show("列名不存在或不匹配,请检查表头是否存在换行。");
}
finally
{
AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomainOnAssemblyResolve;
}
}
[RelayCommand]
private void Check()
{
if (CurrentFacilities?.Count == 0 || Instances?.Count == 0)
{
return;
}
foreach (var EAMData in CurrentFacilities)
{
//var b = Instances.Any(ins => ins.Number.Contains(EAMData.EAMCode));
foreach (var ins in Instances)
{
if (!string.IsNullOrEmpty(ins.Number) && ins.Number.Contains(EAMData.EAMCode))
{
EAMData.IsMapped = true;
ins.IsMapped = true;
break;
}
}
}
CurrentFacilities = [.. CurrentFacilities.OrderBy(fa => fa.IsMapped)];
Instances = [.. Instances.OrderBy(ins => ins.IsMapped)];
}
[RelayCommand]
private void ShowFacility(object obj)
{
if (obj is not IFacility model)
{
return;
}
handler.Raise(uiapp =>
{
var uidoc = uiapp.ActiveUIDocument;
Document doc = uidoc.Document;
if (!model.Instance.IsValidObject)
{
return;
}
//if (model.Instance.IsHidden(uidoc.ActiveView))
//{
// return;
//}
//if (uidoc.ActiveView is not View3D view3d)
//{
// view3d = doc.QueryElementsByType<View3D>().FirstElement() as View3D;
//}
var b = IsVisible(doc.ActiveView.Id, model.Instance);
if (!b)
{
MessageBox.Show("提示", "该构件在当前视图不可见");
return;
}
var box = model.Instance.get_BoundingBox(uidoc.ActiveGraphicalView);
var uiView = uidoc.GetOpenUIViews().FirstOrDefault(v => v.ViewId == uidoc.ActiveGraphicalView.Id);
uiView!.ZoomAndCenterRectangle(box.Min, box.Max);
uidoc.Selection.SetElementIds([model.Instance.Id]);
});
}
private static bool IsVisible(ElementId viewId, Element elem)
{
if (FilteredElementCollector.IsViewValidForElementIteration(elem.Document, viewId)) // 某类视图不能使用 FilteredElementCollector
{
var fec = new FilteredElementCollector(elem.Document, viewId).ToElementIds();
return fec.Any(id => id == elem.Id);
}
return false;
}
private Assembly CurrentDomainOnAssemblyResolve(object sender, ResolveEventArgs args)
{
if (!args.Name.Contains("ComponentModel.Annotations"))
{
return null;
}
string assemblyFile = Path.Combine(GlobalVariables.DirAssembly, "System.ComponentModel.Annotations.dll");
return File.Exists(assemblyFile) ? Assembly.LoadFrom(assemblyFile) : null;
}
partial void OnSelectedStationChanged(string oldValue, string newValue)
{
if (!string.IsNullOrEmpty(newValue))
{
CurrentFacilities = Facilities.Where(fa => fa.StationName == newValue).ToList();
var group = CurrentFacilities.GroupBy(fa => fa.System);
FacilitySystems = [.. group.Select(g => g.Key)];
FacilitySystems.Insert(0, "<请选择系统>");
}
}
partial void OnSelectedSystemChanged(string oldValue, string newValue)
{
if (newValue == "<请选择系统>")
{
CurrentFacilities = Facilities.Where(fa => fa.System == newValue).ToList();
return;
}
if (!string.IsNullOrEmpty(newValue))
{
CurrentFacilities = CurrentFacilities.Where(fa => fa.System == newValue).ToList();
}
}
public List<EAMData> Facilities { get; }
public List<string> Stations { get; }
}
public class EAMData : ObservableObject
{
private bool? isMapped = false;
[ExcelTableColumn("是否匹配", true)]
public bool? IsMapped { get => isMapped; set => SetProperty(ref isMapped, value); }
/// <summary>
/// 线路名称
/// </summary>
[ExcelTableColumn("LINE_NAME")]
public string LineName { get; set; }
/// <summary>
/// EAM编码
/// </summary>
[ExcelTableColumn("OBJ_CODE")]
public string EAMCode { get; set; }
/// <summary>
/// 设备名称
/// </summary>
[ExcelTableColumn("NAME")]
public string Name { get; set; }
/// <summary>
/// 站点名称
/// </summary>
[ExcelTableColumn("WP_NAME", true)]
public string StationName { get; set; }
/// <summary>
/// 系统
/// </summary>
[ExcelTableColumn("SYSTEM", true)]
public string System { get; set; }
}
}