· 5 months ago · Apr 23, 2025, 09:50 AM
1DatabaseHelper.cs:
2namespace OrderTracker
3{
4 using System.Data.SQLite;
5
6 public static class DatabaseHelper
7 {
8 private static string connectionString = "Data Source=Data/orders.db;Version=3;";
9
10 public static void InitializeDatabase()
11 {
12 if (!File.Exists("Data/orders.db"))
13 {
14 SQLiteConnection.CreateFile("Data/orders.db");
15 }
16
17 using (SQLiteConnection connection = new SQLiteConnection(connectionString))
18 {
19 connection.Open();
20 string createTableQuery = @"
21 CREATE TABLE IF NOT EXISTS Orders (
22 Id INTEGER PRIMARY KEY AUTOINCREMENT,
23 ClientName TEXT NOT NULL,
24 ServiceType TEXT NOT NULL,
25 Status TEXT DEFAULT 'Новый',
26 CreatedAt TEXT DEFAULT CURRENT_TIMESTAMP
27 )";
28 new SQLiteCommand(createTableQuery, connection).ExecuteNonQuery();
29 }
30 }
31 }
32}
33
34MainWindow.xaml.cs:
35namespace OrderTracker
36{
37 public partial class MainWindow : Window
38 {
39 private List<Order> allOrders = new List<Order>();
40
41 public MainWindow()
42 {
43 InitializeComponent();
44 InitializeDatabase();
45 LoadOrders();
46 }
47
48 private void InitializeDatabase()
49 {
50 if (!System.IO.File.Exists("Data/orders.db"))
51 {
52 SQLiteConnection.CreateFile("Data/orders.db");
53 }
54
55 using (var connection = new SQLiteConnection("Data Source=Data/orders.db;Version=3;"))
56 {
57 connection.Open();
58 string query = @"
59 CREATE TABLE IF NOT EXISTS Orders (
60 Id INTEGER PRIMARY KEY AUTOINCREMENT,
61 OrderNumber TEXT NOT NULL UNIQUE,
62 ClientName TEXT NOT NULL,
63 PhoneNumber TEXT,
64 Email TEXT,
65 ServiceType TEXT NOT NULL,
66 Status TEXT DEFAULT 'Новый',
67 CreatedAt TEXT DEFAULT CURRENT_TIMESTAMP,
68 Deadline TEXT,
69 Price REAL,
70 Comments TEXT
71 )";
72 new SQLiteCommand(query, connection).ExecuteNonQuery();
73 }
74 }
75
76 private void LoadOrders()
77 {
78 allOrders = new List<Order>();
79
80 using (var connection = new SQLiteConnection("Data Source=Data/orders.db;Version=3;"))
81 {
82 connection.Open();
83 string query = "SELECT * FROM Orders";
84 var command = new SQLiteCommand(query, connection);
85 using (var reader = command.ExecuteReader())
86 {
87 while (reader.Read())
88 {
89 allOrders.Add(new Order
90 {
91 Id = reader.GetInt32(reader.GetOrdinal("Id")),
92 OrderNumber = reader.IsDBNull(reader.GetOrdinal("OrderNumber")) ? null : reader.GetString(reader.GetOrdinal("OrderNumber")),
93 ClientName = reader.GetString(reader.GetOrdinal("ClientName")),
94 PhoneNumber = reader.IsDBNull(reader.GetOrdinal("PhoneNumber")) ? null : reader.GetString(reader.GetOrdinal("PhoneNumber")),
95 ServiceType = reader.GetString(reader.GetOrdinal("ServiceType")),
96 Status = reader.GetString(reader.GetOrdinal("Status")),
97 CreatedAt = DateTime.Parse(reader.GetString(reader.GetOrdinal("CreatedAt")))
98 });
99 }
100 }
101 }
102
103 ApplyFilters();
104 }
105
106 private void ApplyFilters()
107 {
108 if (SearchTextBox == null || FilterComboBox == null || OrdersGrid == null)
109 return;
110
111 string searchText = SearchTextBox.Text?.ToLower() ?? "";
112 string statusFilter = (FilterComboBox.SelectedItem as ComboBoxItem)?.Content.ToString() ?? "Все";
113
114 var filtered = allOrders.Where(order =>
115 (statusFilter == "Все" || order.Status == statusFilter) &&
116 (string.IsNullOrWhiteSpace(searchText) ||
117 (order.ClientName?.ToLower().Contains(searchText) ?? false) ||
118 (order.OrderNumber?.ToLower().Contains(searchText) ?? false)))
119 .ToList();
120
121 OrdersGrid.ItemsSource = filtered;
122 }
123
124 private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
125 {
126 ApplyFilters();
127 }
128
129 private void FilterComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
130 {
131 ApplyFilters();
132 }
133
134 private void AddOrderButton_Click(object sender, RoutedEventArgs e)
135 {
136 var addOrderWindow = new AddOrderWindow();
137 if (addOrderWindow.ShowDialog() == true)
138 {
139 LoadOrders();
140 }
141 }
142
143 private void CopyPhoneMenuItem_Click(object sender, RoutedEventArgs e)
144 {
145 if (OrdersGrid.SelectedItem is Order selectedOrder && !string.IsNullOrEmpty(selectedOrder.PhoneNumber))
146 {
147 Clipboard.SetText(selectedOrder.PhoneNumber);
148 ShowSnackbarMessage($"Телефон скопирован: {selectedOrder.PhoneNumber}");
149 }
150 }
151
152 private void CopyNameMenuItem_Click(object sender, RoutedEventArgs e)
153 {
154 if (OrdersGrid.SelectedItem is Order selectedOrder)
155 {
156 Clipboard.SetText(selectedOrder.ClientName);
157 ShowSnackbarMessage($"Имя скопировано: {selectedOrder.ClientName}");
158 }
159 }
160
161 private void ShowSnackbarMessage(string message)
162 {
163 MainSnackbar.MessageQueue?.Enqueue(
164 message,
165 null,
166 null,
167 null,
168 false,
169 true,
170 TimeSpan.FromSeconds(2));
171 }
172 }
173
174
175
176
177 public class Order
178 {
179 public int Id { get; set; }
180 public string OrderNumber { get; set; }
181 public string ClientName { get; set; }
182 public string PhoneNumber { get; set; }
183 public string ServiceType { get; set; }
184 public string Status { get; set; }
185 public DateTime CreatedAt { get; set; }
186 }
187}
188
189MainWindow.xaml:
190<Window x:Class="OrderTracker.MainWindow"
191 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
192 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
193 xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
194 Title="Трекер заказов" Height="450" Width="800">
195 <Grid>
196 <Grid.RowDefinitions>
197 <RowDefinition Height="Auto"/>
198 <RowDefinition Height="*"/>
199 <RowDefinition Height="Auto"/>
200 </Grid.RowDefinitions>
201
202 <!-- Панель поиска и фильтров -->
203 <StackPanel Grid.Row="0" Orientation="Horizontal" Margin="5">
204 <TextBox x:Name="SearchTextBox" Width="200" Margin="5"
205 TextChanged="SearchTextBox_TextChanged"/>
206 <ComboBox x:Name="FilterComboBox" Width="150" Margin="5"
207 SelectedIndex="0"
208 SelectionChanged="FilterComboBox_SelectionChanged">
209 <ComboBoxItem>Все</ComboBoxItem>
210 <ComboBoxItem>Новые</ComboBoxItem>
211 <ComboBoxItem>В работе</ComboBoxItem>
212 <ComboBoxItem>Завершённые</ComboBoxItem>
213 </ComboBox>
214
215 <!-- Кнопка добавления справа -->
216 <Button x:Name="AddOrderButton"
217 Grid.Row="0"
218 Content="Добавить заказ"
219 Width="120"
220 Height="30"
221 Margin="5,5,10,5"
222 HorizontalAlignment="Right"
223 Click="AddOrderButton_Click"/>
224 </StackPanel>
225
226 <!-- Таблица заказов -->
227 <DataGrid x:Name="OrdersGrid"
228 Grid.Row="1"
229 Margin="10"
230 AutoGenerateColumns="False">
231 <DataGrid.ContextMenu>
232 <ContextMenu>
233 <MenuItem Header="Копировать телефон" Click="CopyPhoneMenuItem_Click"/>
234 <MenuItem Header="Копировать имя" Click="CopyNameMenuItem_Click"/>
235 </ContextMenu>
236 </DataGrid.ContextMenu>
237 <DataGrid.Columns>
238 <DataGridTextColumn Header="ID" Binding="{Binding Id}" Width="Auto"/>
239 <DataGridTextColumn Header="Номер заказа" Binding="{Binding OrderNumber}" Width="*"/>
240 <DataGridTextColumn Header="Клиент" Binding="{Binding ClientName}" Width="*"/>
241 <DataGridTextColumn Header="Телефон" Binding="{Binding PhoneNumber}" Width="*"/>
242 <DataGridTextColumn Header="Услуга" Binding="{Binding ServiceType}" Width="*"/>
243 <DataGridTextColumn Header="Статус" Binding="{Binding Status}" Width="*"/>
244 </DataGrid.Columns>
245 </DataGrid>
246
247 <!-- Snackbar уведомления -->
248 <materialDesign:Snackbar x:Name="MainSnackbar"
249 Grid.Row="2"
250 HorizontalAlignment="Left"
251 VerticalAlignment="Bottom"
252 Margin="20"/>
253 </Grid>
254</Window>
255
256AddOrderWindow.xaml:
257<Window x:Class="OrderTracker.AddOrderWindow"
258 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
259 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
260 Title="Добавить новый заказ"
261 Height="300"
262 Width="400"
263 WindowStartupLocation="CenterOwner">
264 <Grid Margin="10">
265 <Grid.RowDefinitions>
266 <RowDefinition Height="Auto"/>
267 <RowDefinition Height="Auto"/>
268 <RowDefinition Height="Auto"/>
269 <RowDefinition Height="*"/>
270 <RowDefinition Height="Auto"/>
271 </Grid.RowDefinitions>
272
273 <Label Content="Имя клиента:" Grid.Row="0"/>
274 <TextBox x:Name="ClientNameTextBox" Grid.Row="1" Margin="0,0,0,10"/>
275
276 <Label Content="Тип услуги:" Grid.Row="2"/>
277 <ComboBox x:Name="ServiceTypeComboBox" Grid.Row="3" Margin="0,0,0,20">
278 <ComboBoxItem>Вывеска</ComboBoxItem>
279 <ComboBoxItem>Баннер</ComboBoxItem>
280 <ComboBoxItem>Визитка</ComboBoxItem>
281 <ComboBoxItem>Другое</ComboBoxItem>
282 </ComboBox>
283
284 <StackPanel Grid.Row="4" Orientation="Horizontal" HorizontalAlignment="Right">
285 <Button Content="Отмена" Width="80" Margin="0,0,10,0" Click="CancelButton_Click"/>
286 <Button Content="Сохранить" Width="80" Click="SaveButton_Click"/>
287 </StackPanel>
288 </Grid>
289</Window>
290
291AddOrderWindow.xaml.cs:
292namespace OrderTracker
293{
294 public partial class AddOrderWindow : Window
295 {
296 public AddOrderWindow()
297 {
298 InitializeComponent();
299 }
300
301 private void SaveButton_Click(object sender, RoutedEventArgs e)
302 {
303 // Проверка заполнения имени клиента
304 if (string.IsNullOrWhiteSpace(ClientNameTextBox.Text))
305 {
306 MessageBox.Show("Пожалуйста, введите имя клиента", "Ошибка",
307 MessageBoxButton.OK, MessageBoxImage.Warning);
308 ClientNameTextBox.Focus();
309 return;
310 }
311
312 // Проверка выбранной услуги
313 if (ServiceTypeComboBox.SelectedItem == null)
314 {
315 MessageBox.Show("Пожалуйста, выберите тип услуги", "Ошибка",
316 MessageBoxButton.OK, MessageBoxImage.Warning);
317 ServiceTypeComboBox.Focus();
318 return;
319 }
320
321 string orderNumber = GenerateOrderNumber();
322
323 using (var connection = new SQLiteConnection("Data Source=Data/orders.db;Version=3;"))
324 {
325 connection.Open();
326 string query = @"INSERT INTO Orders (OrderNumber, ClientName, ServiceType, Status)
327 VALUES (@number, @name, @service, @status)";
328
329 var command = new SQLiteCommand(query, connection);
330 command.Parameters.AddWithValue("@number", orderNumber);
331 command.Parameters.AddWithValue("@name", ClientNameTextBox.Text);
332 command.Parameters.AddWithValue("@service", (ServiceTypeComboBox.SelectedItem as ComboBoxItem)?.Content.ToString());
333 command.Parameters.AddWithValue("@status", "Новый");
334 }
335
336 MessageBox.Show($"Заказ {orderNumber} успешно создан!", "Успех",
337 MessageBoxButton.OK, MessageBoxImage.Information);
338 DialogResult = true;
339 Close();
340 }
341
342 private string GenerateOrderNumber()
343 {
344 return $"ORD-{DateTime.Now:yyyyMMdd}-{new Random().Next(1000, 9999)}";
345 }
346
347 private void CancelButton_Click(object sender, RoutedEventArgs e)
348 {
349 DialogResult = false;
350 Close();
351 }
352 }
353}