C3032
2025-12-20 d0ded5cd9bf5070a120bad58b5be21fe2ac6a4ff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using SmartScanner.OperateLog;
using Newtonsoft.Json;
using static SmartScanner.IDViewerDefines;
using static SmartScanner.IDViewerSDK;
namespace SmartScanner
{
    /// <summary>
    /// ProductManager.xaml 的交互逻辑
    /// </summary>
    public partial class ProductManager : Window
    {
        private readonly ObservableCollection<KeyValuePair<int, string>> _ipMapping = new ObservableCollection<KeyValuePair<int, string>>();
        private ObservableCollection<string> _availableIPs = new ObservableCollection<string>();
        private const string ConfigFile = "connection_order.json";
        IDDeviceInfo[] deviceInfo = new IDDeviceInfo[100];
 
        public ProductManager()
        {
            InitializeComponent();
            long result = IDVIEWER_Init_();
            dgMapping.ItemsSource = _ipMapping;
            cmbIP.ItemsSource = _availableIPs;
            RefreshDeviceList();
        }
        public void SetControlsEnabled(bool isEnabled)
        {
            // 禁用或启用所有可编辑的控件
            //LoadConfig_RJ.IsEnabled = isEnabled;
            cmbOrder.IsEnabled = isEnabled;
            cmbIP.IsEnabled = isEnabled;
            DeviceRefresh_PM.IsEnabled = isEnabled;
            AddMapping_PM.IsEnabled = isEnabled;
            SaveConfig_PM.IsEnabled = isEnabled;
            //LoadConfig_PM.IsEnabled = isEnabled;
            // ... 其他需要控制的控件
 
        }
 
        private void RefreshDeviceList()
        {
            try
            {
                //获取设备列表句柄
                IntPtr devicesListHandle = IDVIEWER_DiscoveryDevices_(500);
 
                // 获取设备总数
                int deviceCount = (int)IDVIEWER_GetDevicesLength_(devicesListHandle);
 
                // 生成顺序号选项(1~N)
                cmbOrder.ItemsSource = Enumerable.Range(1, deviceCount).ToList();
                cmbOrder.SelectedIndex = 0;
                List<string> ips = new List<string>();
                for (int i = 0; i < deviceCount; i++)
                {
                    //获取相机IP
                    IDViewerSDK.IDVIEWER_SelectIDDeviceInfo_(devicesListHandle, ref deviceInfo[i], (uint)i);
                    string deviceIP = deviceInfo[i].cameraIP.Trim();
                    ips.Add(deviceIP);
                }
                // 获取可用IP列表
                ips.Where(IsValidIP).ToList();
                _availableIPs.Clear();
                foreach (var ip in ips)
                {
                    _availableIPs.Add(ip);
                }
                tbStatus.Text = $"检测到 {deviceCount} 台设备 | 可用IP:{ips.Count} 个";
            }
            catch (Exception ex)
            {
                MessageBox.Show($"设备检测失败:{ex.Message}");
            }
        }
 
        private void BtnAddMapping_Click(object sender, RoutedEventArgs e)
        {
            if (cmbOrder.SelectedItem == null || cmbIP.SelectedItem == null)
            {
                MessageBox.Show("请选择顺序和IP地址");
                return;
            }
 
            int selectedOrder = (int)cmbOrder.SelectedItem;
            string selectedIP = cmbIP.SelectedItem.ToString();
            // 检查顺序冲突
            if (_ipMapping.Any(x => x.Key == selectedOrder))
            {
                MessageBox.Show("该顺序已分配,请先移除原有分配");
                return;
            }
 
            // 检查IP重复
            if (_ipMapping.Any(x => x.Value == selectedIP))
            {
                MessageBox.Show("该IP已分配顺序");
                return;
            }
 
            _ipMapping.Add(new KeyValuePair<int, string>(selectedOrder, selectedIP));
            SortMapping();
        }
 
        private void DeleteMapping_Click(object sender, RoutedEventArgs e)
        {
            if (dgMapping.SelectedItem is KeyValuePair<int, string> item)
            {
                _ipMapping.Remove(item);
                SortMapping();
            }
        }
 
        private void SortMapping()
        {
            var sorted = _ipMapping
                .OrderBy(x => x.Key)
                .ToList();
 
            _ipMapping.Clear();
            foreach (var item in sorted)
            {
                _ipMapping.Add(item);
            }
        }
 
        private void BtnRefreshDevices_Click(object sender, RoutedEventArgs e) => RefreshDeviceList();
 
        // 保存/加载方法
        private void BtnSave_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var config = new
                {
                    LastModified = DateTime.Now,
                    Mapping = _ipMapping.ToList()
                };
 
                File.WriteAllText(ConfigFile, JsonConvert.SerializeObject(config, Formatting.Indented));
                MessageBox.Show("配置保存成功");
                // 记录日志
                OperateLogService.LogOperation(
                    "映射表修改",
                    $"映射表修改为: {ConfigFile}",
                    null);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"保存失败:{ex.Message}");
            }
        }
        private void BtnLoad_Click(object sender, RoutedEventArgs e)
        {
          var loadedMapping = LoadConfig();
            if (loadedMapping.Count > 0)
            {
                _ipMapping.Clear(); // 清空当前映射
                foreach (var item in loadedMapping)
                {
                    _ipMapping.Add(item); // 添加加载的配置
                }
                SortMapping(); // 重新排序
                RefreshMappingDisplay(); // 刷新界面显示
                MessageBox.Show("配置加载成功");
            }
        }
        private void RefreshMappingDisplay()
        {
            // 绑定数据到 DataGrid
            dgMapping.ItemsSource = null; // 先清空绑定
            dgMapping.ItemsSource = _ipMapping.ToList(); // 重新绑定
        }
 
        public List<KeyValuePair<int, string>> LoadConfig()
        {
            try
            {
                if (File.Exists(ConfigFile))
                {
                    var json = File.ReadAllText(ConfigFile);
                    var config = JsonConvert.DeserializeObject<dynamic>(json);
                    var mapping = new List<KeyValuePair<int, string>>();
                    foreach (var item in config.Mapping)
                    {
                        mapping.Add(new KeyValuePair<int, string>(
                            (int)item.Key,
                            (string)item.Value));
                    }
                    return mapping;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载映射表失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            return new List<KeyValuePair<int, string>>();
        }
        private static bool IsValidIP(string ip) => Regex.IsMatch(ip,
        @"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");
    }
}