using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Web.UI.WebControls; using System.Windows.Controls; using System.Windows.Forms; using System.Windows.Input; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Media3D; using Bricscad.EditorInput; using ImTools; using Newtonsoft.Json; using Prism.Services.Dialogs; using SWS.CAD.Base; using SWS.Commons; using SWS.Electrical.Models; using SWS.Model; using SWS.Service; using SWS.Share; using SWS.WPF.ViewModels; using Teigha.DatabaseServices; using Teigha.Geometry; using Teigha.GraphicsSystem; using Telerik.Windows.Controls; using Unity; using Visibility = System.Windows.Visibility; namespace SWS.Electrical.ViewModels { public class DialogGenerateBOMViewModel : DialogBase, IDialogAware { private ObservableCollection _listDrawings = new ObservableCollection(); /// /// 图纸树 /// public ObservableCollection listDrawings { get { return this._listDrawings; } set { if (value != this._listDrawings) { this._listDrawings = value; RaisePropertyChanged(nameof(listDrawings)); } } } private ObservableCollection _listBomDrawings = new ObservableCollection(); /// /// 材料表列表 /// public ObservableCollection listBomDrawings { get { return this._listBomDrawings; } set { if (value != this._listBomDrawings) { this._listBomDrawings = value; RaisePropertyChanged(nameof(listBomDrawings)); } } } private ObservableCollection _listMsg = new ObservableCollection(); /// /// 信息列表 /// public ObservableCollection listMsg { get { return this._listMsg; } set { if (value != this._listMsg) { this._listMsg = value; RaisePropertyChanged(nameof(listMsg)); } } } /// /// 命令事件 生成材料表 /// public ICommand Command_StartGenerate { get; set; } /// /// 命令事件 选择节点 /// public ICommand Command_ChangeCheck { get; set; } DrawingServce _ServiceDrawing; AnnexesService _ServiceAnnexes; DrawingCatalogueService _ServiceDrawingCatalogue; PlotBOMService _ServicePlotBOM; private bool isGenerate = false;//是否正在生成材料表 private string dwgName = string.Empty; public DialogGenerateBOMViewModel() { Command_StartGenerate = new DelegateCommand(onStartGenerate); Command_ChangeCheck = new DelegateCommand(onChangeCheck); title = "材料表自动生成"; _ServiceDrawing = GlobalObject.container.Resolve(); _ServiceAnnexes = GlobalObject.container.Resolve(); _ServicePlotBOM = GlobalObject.container.Resolve(); _ServiceDrawingCatalogue = GlobalObject.container.Resolve(); } public string Title => ""; public event Action RequestClose; public bool CanCloseDialog() { return true; } public void OnDialogClosed() { } #region 树节点操作 /// /// 改变子节点选中状态 /// private void ChangeChild(TreeModel model, bool isChecked) { if (model.ChildNodes != null && model.ChildNodes.Any()) { foreach (var item in model.ChildNodes) { item.IsChecked = isChecked; ChangeChild(item, isChecked); } } } /// /// 改变父节点选中状态 /// private void ChangeParent(TreeModel model, bool isChecked) { if (!string.IsNullOrEmpty(model.parentId) && model.parentId != "0") { var parentNode = TreeHelper.GetTreeModel(listDrawings.ToList(), model.parentId); if (parentNode != null) { if (isChecked) { bool flag = true; foreach (var child in parentNode.ChildNodes) { if (child.IsChecked != true) { flag = false; break; } } parentNode.IsChecked = flag; ChangeParent(parentNode, flag); } else { parentNode.IsChecked = isChecked; ChangeParent(parentNode, isChecked); } } } } /// /// 节点选中状态改变 /// /// /// public void ChangeChecked(string id, bool isChecked) { var node = TreeHelper.GetTreeModel(listDrawings.ToList(), id); if (node == null) { return; } if (isChecked) // 如果节点被选中 { if (node.ChildNodes != null) { foreach (var item in node.ChildNodes) { ChangeChild(item, isChecked); item.IsChecked = true; } } if (!string.IsNullOrEmpty(node.parentId) && node.parentId != "0") { ChangeParent(node, isChecked); } } else if (isChecked == false) // 如果节点未选中 { if (node.ChildNodes != null) { foreach (var item in node.ChildNodes) { item.IsChecked = false; ChangeChild(item, isChecked); } } if (!string.IsNullOrEmpty(node.parentId) && node.parentId != "0") { ChangeParent(node, isChecked); } } } /// /// 过滤文件夹:[材料表],[封面、目录、设计说明] /// /// private void FilterNodes(TreeModel treeModel) { if (treeModel.ChildNodes != null && treeModel.ChildNodes.Any()) { List nodes = new List(); foreach (var item in treeModel.ChildNodes) { if (item.NodeType == "0" && (item.ChildNodes == null || !item.ChildNodes.Any())) { nodes.Add(item); }//过滤无图纸文件的文件 if (item.Text.Equals("材料表") || item.Text.Equals("封面、目录、设计说明")) { nodes.Add(item); } else { FilterNodes(item); } } foreach (var item in nodes) { treeModel.ChildNodes.Remove(item); } return; } else { return; } } /// /// 获取子节点的图纸数量 /// /// /// private int GetChildCount(TreeModel treeModel) { int count = 0; List listModel = new List(); if (treeModel.ChildNodes != null && treeModel.ChildNodes.Any()) { foreach (var item in treeModel.ChildNodes) { if (item.Text.ToLower().EndsWith(".dwg")) { count++; } else { var sum = GetChildCount(item); count += sum; } } return count; } else { return count; } } /// /// 获取选中的图纸列表 /// /// private List GetDwgIsChecked(List listTree) { List listModel = new List(); foreach (var item in listTree) { if (item.Text.ToLower().EndsWith(".dwg") && item.IsChecked) { listModel.Add(item); continue; } if (item.ChildNodes != null && item.ChildNodes.Any()) { var list = GetDwgIsChecked(item.ChildNodes.ToList()); if (list.Any()) { listModel.AddRange(list); } } } return listModel; } #endregion public async void OnDialogOpened(IDialogParameters parameters) { try { IsBusy = true; BusyContent = "数据加载中..."; AddMsg($"图纸数据加载中..."); List listDwg = new List(); var list = await _ServiceDrawing.GetDrawingCatalogue(); GlobalObject.AllDrawings = list.ToList(); foreach (var item in list) { if (GetChildCount(item) > 0) { //把文件夹的放在图纸前面 var childs = item.ChildNodes.OrderBy(a => a.NodeType).ToList(); item.ChildNodes = new ObservableCollection(childs); //过滤材料表文件夹,过滤:封面、目录、设计说明 FilterNodes(item); listDwg.Add(item); } } listDrawings = new ObservableCollection(listDwg); AddMsg($"图纸数据加载完成"); } catch (Exception ex) { MessageBox.Show("DialogOpened异常:" + ex.Message); } finally { IsBusy = false; } } /// ///改变节点选中状态 /// /// public void onChangeCheck(object o) { var checkbox = o as System.Windows.Controls.CheckBox; var id = checkbox.Tag.ToString(); var isChecked = checkbox.IsChecked.Value; var node = TreeHelper.GetTreeModel(listDrawings.ToList(), id); if (node == null) { return; } if (isChecked) // 如果节点被选中 { if (node.ChildNodes != null) { foreach (var item in node.ChildNodes) { ChangeChild(item, isChecked); item.IsChecked = true; } } if (!string.IsNullOrEmpty(node.parentId) && node.parentId != "0") { ChangeParent(node, isChecked); } } else if (isChecked == false) // 如果节点未选中 { if (node.ChildNodes != null) { foreach (var item in node.ChildNodes) { item.IsChecked = false; ChangeChild(item, isChecked); } } if (!string.IsNullOrEmpty(node.parentId) && node.parentId != "0") { ChangeParent(node, isChecked); } } } /// /// 自动生成材料表 /// /// public async void onStartGenerate(object o) { if (isGenerate) { MessageBox.Show("正在生成材料表,请勿操作..."); return; } var msg = string.Empty; try { //AddText(); //return; var list = GetDwgIsChecked(listDrawings.ToList()); List listBom = new List(); foreach (var item in list) { listBom.Add(new DtoBomDrawings() { DrawingFileID = item.ID, DrawingFileName = item.Text, AutoGenerate = "等待中..." }); } listBomDrawings = new ObservableCollection(listBom); isGenerate = true; listMsg.Clear(); foreach (var dwg in listBomDrawings) { if (dwg.AutoGenerate == "已生成") { AddMsg($"当前图纸[{dwg.DrawingFileName}]的材料表已绘制,跳至下一个图纸"); continue; } if (dwg.AutoGenerate == "已存在") { AddMsg($"当前图纸[{dwg.DrawingFileName}]的材料表已存在,跳至下一个图纸"); //continue; } if (dwg.AutoGenerate == "无材料信息") { AddMsg($"当前图纸[{dwg.DrawingFileName}]无材料信息,跳至下一个图纸"); continue; } string folderpath = GlobalObject.GetDwgPath(dwg.DrawingFileID); string filepath = Path.Combine(GlobalObj.LocalWorkDir, GlobalObject.curProject.ProjectName, folderpath, $"材料表\\{dwg.DrawingFileName}"); if (File.Exists(filepath)) { AddMsg($"当前图纸[{dwg.DrawingFileName}]的材料表已存在,跳至下一个图纸", false); dwg.AutoGenerate = "已存在"; //continue; } var listBomGroup = await _ServicePlotBOM.GetBOMGroupInfo(dwg.DrawingFileID); dwg.AutoGenerate = "正在生成..."; AddMsg($"开始生成图纸[{dwg.DrawingFileName}]的材料表..."); if (listBomGroup == null || !listBomGroup.Any()) { AddMsg($"当前图纸无材料分组信息,跳至下一个图纸"); dwg.AutoGenerate = "无材料信息"; continue; } msg = GenerateBOM(dwg, filepath, listBomGroup); if (!string.IsNullOrEmpty(msg)) { AddMsg($"材料表生成失败,信息:" + msg, false); continue; } //下载图标图纸文件 //filePath = Path.Combine(GlobalObject.GetCacheFolder(), $"{tag.TagNumber}.dwg"); //AddMsg($"元件图纸:{tag.TagNumber}, 开始下载..."); //msg = await _ServiceAnnexes.DownloadFile(filePath, obj.FolderId); //if (!string.IsNullOrEmpty(msg)) //{ // AddMsg($"元件图纸下载失败,信息:" + msg, false); // continue; //} //AddMsg($"元件图纸:{tag.TagNumber}, 下载成功"); //filePath = "D:\\BricsCAD\\Temp\\测试11.dwg"; dwg.AutoGenerate = "已生成"; AddMsg($"材料表生成成功!"); } AddMsg("操作已完成!"); isGenerate = false; } catch (Exception ex) { MessageBox.Show("异常:" + ex.Message); isGenerate = false; } } /// /// 生成BOM表图纸 /// /// 材料表文件路径 /// 位号分组信息 /// private string GenerateBOM(DtoBomDrawings dtoBOM, string filepath, List listBomGroup) { string msg = string.Empty; //1.创建材料表图纸文件 string folderpath = Path.GetDirectoryName(filepath); string bomName = Path.Combine(folderpath, "BomTemp.dwg"); string dwgName = dtoBOM.DrawingFileName.Substring(0, dtoBOM.DrawingFileName.Length - 4); var flag = General.CreateDwg(folderpath, dwgName); if (!flag) { msg = $"材料表图纸创建失败,路径:{filepath}"; return msg; } //2.读取BOM表配置文件 string strJson = File.ReadAllText("Template\\BomConfig.json"); BomConfig bomComfig = JsonConvert.DeserializeObject(strJson); //3.判断位号分组信息需要分成几张材料表,分页生成材料表 List listTextInfo = new List(); decimal mod = (decimal)listBomGroup.Count / (decimal)bomComfig.RowCount; var page = Math.Ceiling(mod);//总的A4表格页数 小数点向上取整数 for (int i = 0; i < page; i++) { listTextInfo = new List(); int count = (i + 1) == page ? (listBomGroup.Count % bomComfig.RowCount) : bomComfig.RowCount; for (int j = 0; j < count; j++) { var index = i * bomComfig.RowCount + j; var bomInfo = listBomGroup[index]; #region 序号 var dto = new DtoCadTextInfo(); dto.Text = (j + 1).ToString(); dto.Position = new Point3d(bomComfig.Column1X, bomComfig.Column1Y - (j * bomComfig.RowHeight), 0); dto.IsMText = false; dto.Height = 4; dto.Width = 20; dto.Align = 1; listTextInfo.Add(dto); #endregion #region 图标 #endregion #region 数量 dto = new DtoCadTextInfo(); dto.Text = (bomInfo.Count).ToString(); dto.Position = new Point3d(bomComfig.Column3X, bomComfig.Column3Y - (j * bomComfig.RowHeight), 0); dto.IsMText = false; dto.Height = 4; dto.Width = 20; dto.Align = 1; listTextInfo.Add(dto); #endregion #region 型号 dto = new DtoCadTextInfo(); dto.Text = (bomInfo.Model).ToString(); dto.Position = new Point3d(bomComfig.Column4X, bomComfig.Column4Y - (j * bomComfig.RowHeight), 0); dto.IsMText = false; dto.Height = 4; dto.Width = 20; dto.Align = 1; listTextInfo.Add(dto); #endregion #region 规格 dto = new DtoCadTextInfo(); dto.Text = (bomInfo.Spec).ToString(); dto.Position = new Point3d(bomComfig.Column5X, bomComfig.Column5Y - (j * bomComfig.RowHeight), 0); dto.IsMText = false; dto.Height = 4; dto.Width = 20; dto.Align = 1; listTextInfo.Add(dto); #endregion #region 备注 dto = new DtoCadTextInfo(); dto.Text = (bomInfo.Remark).ToString(); dto.Position = new Point3d(bomComfig.Column6X, bomComfig.Column6Y - (j * bomComfig.RowHeight), 0); dto.IsMText = false; dto.Height = 4; dto.Width = 20; dto.Align = 1; listTextInfo.Add(dto); #endregion } #region 把材料信息插入材料表图纸里 File.Copy("Template\\材料表.dwg", bomName, true); General.OpenDwg(bomName); General.InsertTextInfo(listTextInfo); General.SaveAndCloseDwg(bomName); General.OpenDwg(filepath); //计算该页材料表是第几行第几列的 double x, y = 0;//坐标x,y decimal row = (decimal)i / (decimal)bomComfig.RowPageCount;//row表示行数,在第几行 row = Math.Floor(row); var column = i % bomComfig.RowPageCount;//column表示列数,在第几列 x = column == 0 ? 0 : (double)column * bomComfig.Width; y = row == 0 ? 0 : 0 - (double)row * bomComfig.Height; var position = new Point3d(x, y, 0); General.AddBlockDWG(bomName, $"材料表{i + 1}", position); General.SaveAndCloseDwg(filepath); #endregion } File.Delete(bomName); General.OpenDwg(filepath); return msg; } #region 添加提示信息 /// /// 添加提示信息 /// /// 信息 /// 是否成功 private void AddMsg(string msg, bool isSucc = true) { try { TextBlock tb = new TextBlock(); tb.Text = DateTime.Now.ToString("HH:mm:ss") + "==>> " + msg; tb.Foreground = isSucc ? Brushes.LightSeaGreen : Brushes.Red; listMsg.Add(tb); } catch (Exception ex) { MessageBox.Show("添加提示信息异常:" + ex.Message); } } #endregion } }