Explorar el Código

新增点位文件导入导出功能(支持XML批量操作)

在PlcPointParamsViewModel和PlcPointParams.xaml中实现了产品点位的导入/导出功能。支持将所有点位批量导出为XML文件,或从XML文件导入并覆盖当前点位集合。新增了相关命令、DTO类及UI按钮,提升了点位数据的备份、迁移和恢复能力。
徐孝锋 hace 7 meses
padre
commit
74ae3061ec

+ 202 - 0
TeamAAS-VM/ViewModels/Product/PlcPointParamsViewModel.cs

@@ -30,6 +30,9 @@ using TeamAAS_VP.Resources.Languages;
 using TeamAAS_VP.Services;
 using TeamAAS_VP.Views.Product;
 using static TeamAAS_VP.ViewModels.Product.AutoCorrectLockPointViewModel;
+using System.IO;
+using System.Xml.Serialization;
+using Microsoft.Win32;
 
 namespace TeamAAS_VP.ViewModels.Product
 {
@@ -352,6 +355,44 @@ namespace TeamAAS_VP.ViewModels.Product
 
         #endregion
 
+        #region DTOs for import/export
+        public class ProductPointsExport
+        {
+            /// <summary>
+            /// 软件版本号
+            /// </summary>
+            public string SoftwareVersion { get; set; }
+
+            /// <summary>
+            /// 产品名称
+            /// </summary>
+            public string ProductName { get; set; }
+
+            /// <summary>
+            /// 产品描述
+            /// </summary>
+            public string ProductDescription { get; set; }
+
+            /// <summary>
+            /// 设备名称
+            /// </summary>
+            public string DeviceName { get; set; }
+
+            /// <summary>
+            /// 创建日期
+            /// </summary>
+            public DateTime? Created { get; set; }
+
+            public List<PlcPoint> PickCameraPoints { get; set; }
+            public List<PlcPoint> PickPoints { get; set; }
+            public List<PlcPoint> SecPosCameraPoints { get; set; }
+            public List<PlcPoint> ScrewCameraPoints { get; set; }
+            public List<PlcPoint> ScrewPoints { get; set; }
+            public List<PlcPoint> QrCodePoints { get; set; }
+            public List<PlcPoint> CheckCameraPoints { get; set; }
+        }
+        #endregion
+
         #region 命令
         private DelegateCommand _NextCommand;
         public DelegateCommand NextCommand =>
@@ -456,6 +497,14 @@ namespace TeamAAS_VP.ViewModels.Product
         public DelegateCommand SetOffsetCommand =>
             _SetOffsetCommand ?? (_SetOffsetCommand = new DelegateCommand(ExecuteSetOffsetCommand));
 
+        private DelegateCommand _ImportPointsCommand;
+        public DelegateCommand ImportPointsCommand =>
+            _ImportPointsCommand ?? (_ImportPointsCommand = new DelegateCommand(ExecuteImportPointsCommand));
+
+        private DelegateCommand _ExportAllPointsCommand;
+        public DelegateCommand ExportAllPointsCommand =>
+            _ExportAllPointsCommand ?? (_ExportAllPointsCommand = new DelegateCommand(ExecuteExportAllPointsCommand));
+
 
         #endregion
 
@@ -1679,6 +1728,159 @@ namespace TeamAAS_VP.ViewModels.Product
 
             });
         }
+
+        /// <summary>
+        /// 导出所有点位到本地文件(XML)
+        /// </summary>
+        void ExecuteExportAllPointsCommand()
+        {
+            try
+            {
+                if (SelectProduct == null)
+                {
+                    MessageBox.Show("未选择产品", Lang.错误, MessageBoxButton.OK, MessageBoxImage.Warning);
+                    return;
+                }
+
+                var dlg = new SaveFileDialog();
+                dlg.Filter = "Plc Product Points File|*.plcproductpoints.xml|All files|*.*";
+                dlg.FileName = SelectProduct != null ? ($"{SelectProduct.Name}_allpoints_{DateTime.Now:yyyyMMdd_HHmmss}.plcproductpoints.xml") : ($"product_points_{DateTime.Now:yyyyMMdd_HHmmss}.plcproductpoints.xml");
+                var res = dlg.ShowDialog();
+                if (res != true) return;
+
+                var filePath = dlg.FileName;
+                // 构建导出对象
+                var export = new ProductPointsExport
+                {
+                    SoftwareVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(),
+                    ProductName = SelectProduct.Name,
+                    ProductDescription = SelectProduct.Description,
+                    DeviceName=_configService.GetDeviceInfo().Station,
+                    Created= DateTime.Now,
+                    PickCameraPoints = SelectProduct.PickCameraPoints?.Select(p => p.Clone()).ToList() ?? new List<PlcPoint>(),
+                    PickPoints = SelectProduct.PickPoints?.Select(p => p.Clone()).ToList() ?? new List<PlcPoint>(),
+                    SecPosCameraPoints = SelectProduct.SecPosCameraPoints?.Select(p => p.Clone()).ToList() ?? new List<PlcPoint>(),
+                    ScrewCameraPoints = SelectProduct.ScrewCameraPoints?.Select(p => p.Clone()).ToList() ?? new List<PlcPoint>(),
+                    ScrewPoints = SelectProduct.ScrewPoints?.Select(p => p.Clone()).ToList() ?? new List<PlcPoint>(),
+                    QrCodePoints = SelectProduct.QrCodePoints?.Select(p => p.Clone()).ToList() ?? new List<PlcPoint>(),
+                    CheckCameraPoints = SelectProduct.CheckCameraPoints?.Select(p => p.Clone()).ToList() ?? new List<PlcPoint>()
+                };
+
+                var serializer = new XmlSerializer(typeof(ProductPointsExport));
+                using (var fs = File.Create(filePath))
+                {
+                    serializer.Serialize(fs, export);
+                }
+                _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = "导出完成", Duration = 1 });
+            }
+            catch (Exception ex)
+            {
+                LogHelper.WriteLogError("导出点位时出错", ex);
+                _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = ex.Message, Duration = 1 });
+            }
+        }
+
+        /// <summary>
+        /// 导入点位文件,覆盖当前点位
+        /// </summary>
+        void ExecuteImportPointsCommand()
+        {
+            try
+            {
+                var dlg = new OpenFileDialog();
+                dlg.Filter = "Plc Points File|*.plcproductpoints.xml|All files|*.*";
+                var res = dlg.ShowDialog();
+                if (res != true) return;
+                var filePath = dlg.FileName;
+
+                // 验证并读取文件(ProductPointsExport)
+                var serializer = new XmlSerializer(typeof(ProductPointsExport));
+                ProductPointsExport import = null;
+                using (var fs = File.OpenRead(filePath))
+                {
+                    try
+                    {
+                        import = (ProductPointsExport)serializer.Deserialize(fs);
+                    }
+                    catch (Exception ex)
+                    {
+                        MessageBox.Show("无效的点位文件或文件已损坏", Lang.错误, MessageBoxButton.OK, MessageBoxImage.Error);
+                        LogHelper.WriteLogError("导入点位文件解析失败", ex);
+                        return;
+                    }
+                }
+
+                if (import == null)
+                {
+                    MessageBox.Show("导入的点位文件为空", Lang.提示, MessageBoxButton.OK, MessageBoxImage.Information);
+                    return;
+                }
+
+                // 提示用户是否覆盖
+                if (MessageBox.Show("确认要导入点位文件并覆盖当前所有点位吗", "导入点位", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
+                {
+                    return;
+                }
+
+                // 覆盖 SelectProduct 下的各类点集合
+                SelectProduct.PickCameraPoints = new ObservableCollection<PlcPoint>(import.PickCameraPoints ?? new List<PlcPoint>());
+                SelectProduct.PickPoints = new ObservableCollection<PlcPoint>(import.PickPoints ?? new List<PlcPoint>());
+                SelectProduct.SecPosCameraPoints = new ObservableCollection<PlcPoint>(import.SecPosCameraPoints ?? new List<PlcPoint>());
+                SelectProduct.ScrewCameraPoints = new ObservableCollection<PlcPoint>(import.ScrewCameraPoints ?? new List<PlcPoint>());
+                SelectProduct.ScrewPoints = new ObservableCollection<PlcPoint>(import.ScrewPoints ?? new List<PlcPoint>());
+                SelectProduct.QrCodePoints = new ObservableCollection<PlcPoint>(import.QrCodePoints ?? new List<PlcPoint>());
+                SelectProduct.CheckCameraPoints = new ObservableCollection<PlcPoint>(import.CheckCameraPoints ?? new List<PlcPoint>());
+
+                // 重新编号每个集合
+                Action<ObservableCollection<PlcPoint>> renumber = (col) =>
+                {
+                    for (int i = 0; i < col.Count; i++) col[i].Number = i + 1;
+                };
+                renumber(SelectProduct.PickCameraPoints);
+                renumber(SelectProduct.PickPoints);
+                renumber(SelectProduct.SecPosCameraPoints);
+                renumber(SelectProduct.ScrewCameraPoints);
+                renumber(SelectProduct.ScrewPoints);
+                renumber(SelectProduct.QrCodePoints);
+                renumber(SelectProduct.CheckCameraPoints);
+
+                // 根据当前 SelectedIndex 切换 Points 绑定到对应集合
+                switch (SelectedIndex)
+                {
+                    case 0:
+                        Points = SelectProduct.PickCameraPoints;
+                        break;
+                    case 1:
+                        Points = SelectProduct.PickPoints;
+                        break;
+                    case 2:
+                        Points = SelectProduct.SecPosCameraPoints;
+                        break;
+                    case 3:
+                        Points = SelectProduct.ScrewCameraPoints;
+                        break;
+                    case 4:
+                        Points = SelectProduct.ScrewPoints;
+                        break;
+                    case 5:
+                        Points = SelectProduct.CheckCameraPoints;
+                        break;
+                    case 6:
+                        Points = SelectProduct.QrCodePoints;
+                        break;
+                    default:
+                        Points = SelectProduct.PickCameraPoints;
+                        break;
+                }
+
+                _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = "导入完成", Duration = 1 });
+            }
+            catch (Exception ex)
+            {
+                LogHelper.WriteLogError("导入点位时出错", ex);
+                _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = ex.Message, Duration = 1 });
+            }
+        }
         #endregion
 
         #region 继承

+ 11 - 0
TeamAAS-VM/Views/Product/PlcPointParams.xaml

@@ -319,6 +319,17 @@
                                     MinWidth="80"
                                     materialDesign:ButtonAssist.CornerRadius="5"
                                     Command="{Binding MovePointDownCommand}" />
+                            <!-- 导入/导出点位文件 -->
+                            <Button Content="导入点位文件"
+                                    Margin="5,2"
+                                    MinWidth="120"
+                                    materialDesign:ButtonAssist.CornerRadius="5"
+                                    Command="{Binding ImportPointsCommand}" />
+                            <Button Content="导出所有点位"
+                                    Margin="5,2"
+                                    MinWidth="120"
+                                    materialDesign:ButtonAssist.CornerRadius="5"
+                                    Command="{Binding ExportAllPointsCommand}" />
                             <Button Content="{lex:Loc CAD导入点位}"
                                     Margin="5,2"
                                     MinWidth="80"