Добавьте файлы проекта.
This commit is contained in:
parent
74cf6d2453
commit
438a7c85cc
18
App.config
Normal file
18
App.config
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
<configSections>
|
||||||
|
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
|
||||||
|
<section name="SKLADm.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
||||||
|
</sectionGroup>
|
||||||
|
</configSections>
|
||||||
|
<startup>
|
||||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
|
||||||
|
</startup>
|
||||||
|
<userSettings>
|
||||||
|
<SKLADm.Properties.Settings>
|
||||||
|
<setting name="SavedStoresJson" serializeAs="String">
|
||||||
|
<value />
|
||||||
|
</setting>
|
||||||
|
</SKLADm.Properties.Settings>
|
||||||
|
</userSettings>
|
||||||
|
</configuration>
|
223
Form1.Designer.cs
generated
Normal file
223
Form1.Designer.cs
generated
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// Этот код создан программой.
|
||||||
|
// Исполняемая версия:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
|
||||||
|
// повторной генерации кода.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace OzonInternalLabelPrinter // Убедитесь, что это ваше пространство имен
|
||||||
|
{
|
||||||
|
partial class Form1
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Обязательная переменная конструктора.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Освободить все используемые ресурсы.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
// Освобождаем ресурсы, созданные в коде Form1.cs
|
||||||
|
_httpClient?.Dispose();
|
||||||
|
_printDocForSetup?.Dispose(); // Добавлено освобождение PrintDocument
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Код, автоматически созданный конструктором форм Windows
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Требуемый метод для поддержки конструктора — не изменяйте
|
||||||
|
/// содержимое этого метода с помощью редактора кода.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.label3 = new System.Windows.Forms.Label();
|
||||||
|
this.txtOfferId = new System.Windows.Forms.TextBox();
|
||||||
|
this.btnGetData = new System.Windows.Forms.Button();
|
||||||
|
this.lblProductName = new System.Windows.Forms.Label();
|
||||||
|
this.lblProductSku = new System.Windows.Forms.Label();
|
||||||
|
this.lblProductBarcode = new System.Windows.Forms.Label();
|
||||||
|
this.btnPrintLabel = new System.Windows.Forms.Button();
|
||||||
|
this.lblStatus = new System.Windows.Forms.Label();
|
||||||
|
this.cmbStores = new System.Windows.Forms.ComboBox();
|
||||||
|
this.btnManageStores = new System.Windows.Forms.Button();
|
||||||
|
this.labelStore = new System.Windows.Forms.Label();
|
||||||
|
this.btnPageSetup = new System.Windows.Forms.Button(); // Объявление кнопки Настройки
|
||||||
|
this.pageSetupDialog1 = new System.Windows.Forms.PageSetupDialog(); // Объявление диалога Настройки
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// label3
|
||||||
|
//
|
||||||
|
this.label3.AutoSize = true;
|
||||||
|
this.label3.Location = new System.Drawing.Point(12, 94); // Скорректировано
|
||||||
|
this.label3.Name = "label3";
|
||||||
|
this.label3.Size = new System.Drawing.Size(51, 13);
|
||||||
|
this.label3.TabIndex = 4;
|
||||||
|
this.label3.Text = "Артикул:";
|
||||||
|
//
|
||||||
|
// txtOfferId
|
||||||
|
//
|
||||||
|
this.txtOfferId.Enabled = false;
|
||||||
|
this.txtOfferId.Location = new System.Drawing.Point(88, 91); // Скорректировано
|
||||||
|
this.txtOfferId.Name = "txtOfferId";
|
||||||
|
this.txtOfferId.Size = new System.Drawing.Size(176, 20);
|
||||||
|
this.txtOfferId.TabIndex = 3; // TabIndex изменен
|
||||||
|
this.txtOfferId.TextChanged += new System.EventHandler(this.txtOfferId_TextChanged);
|
||||||
|
//
|
||||||
|
// btnGetData
|
||||||
|
//
|
||||||
|
this.btnGetData.Enabled = false;
|
||||||
|
this.btnGetData.Location = new System.Drawing.Point(270, 89); // Скорректировано
|
||||||
|
this.btnGetData.Name = "btnGetData";
|
||||||
|
this.btnGetData.Size = new System.Drawing.Size(118, 23);
|
||||||
|
this.btnGetData.TabIndex = 4; // TabIndex изменен
|
||||||
|
this.btnGetData.Text = "Получить данные";
|
||||||
|
this.btnGetData.UseVisualStyleBackColor = true;
|
||||||
|
this.btnGetData.Click += new System.EventHandler(this.btnGetData_Click);
|
||||||
|
//
|
||||||
|
// lblProductName
|
||||||
|
//
|
||||||
|
this.lblProductName.AutoSize = true;
|
||||||
|
this.lblProductName.Location = new System.Drawing.Point(12, 133); // Скорректировано
|
||||||
|
this.lblProductName.Name = "lblProductName";
|
||||||
|
this.lblProductName.Size = new System.Drawing.Size(60, 13);
|
||||||
|
this.lblProductName.TabIndex = 5;
|
||||||
|
this.lblProductName.Text = "Название:";
|
||||||
|
//
|
||||||
|
// lblProductSku
|
||||||
|
//
|
||||||
|
this.lblProductSku.AutoSize = true;
|
||||||
|
this.lblProductSku.Location = new System.Drawing.Point(12, 156); // Скорректировано
|
||||||
|
this.lblProductSku.Name = "lblProductSku";
|
||||||
|
this.lblProductSku.Size = new System.Drawing.Size(51, 13);
|
||||||
|
this.lblProductSku.TabIndex = 6;
|
||||||
|
this.lblProductSku.Text = "Артикул:";
|
||||||
|
//
|
||||||
|
// lblProductBarcode
|
||||||
|
//
|
||||||
|
this.lblProductBarcode.AutoSize = true;
|
||||||
|
this.lblProductBarcode.Location = new System.Drawing.Point(12, 179); // Скорректировано
|
||||||
|
this.lblProductBarcode.Name = "lblProductBarcode";
|
||||||
|
this.lblProductBarcode.Size = new System.Drawing.Size(59, 13);
|
||||||
|
this.lblProductBarcode.TabIndex = 7;
|
||||||
|
this.lblProductBarcode.Text = "Штрихкод:";
|
||||||
|
//
|
||||||
|
// btnPrintLabel
|
||||||
|
//
|
||||||
|
this.btnPrintLabel.Enabled = false;
|
||||||
|
this.btnPrintLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
|
||||||
|
this.btnPrintLabel.Location = new System.Drawing.Point(16, 214); // Скорректировано
|
||||||
|
this.btnPrintLabel.Name = "btnPrintLabel";
|
||||||
|
this.btnPrintLabel.Size = new System.Drawing.Size(373, 33);
|
||||||
|
this.btnPrintLabel.TabIndex = 8; // TabIndex изменен
|
||||||
|
this.btnPrintLabel.Text = "Печать этикетки";
|
||||||
|
this.btnPrintLabel.UseVisualStyleBackColor = true;
|
||||||
|
this.btnPrintLabel.Click += new System.EventHandler(this.btnPrintLabel_Click);
|
||||||
|
//
|
||||||
|
// lblStatus
|
||||||
|
//
|
||||||
|
this.lblStatus.AutoSize = true;
|
||||||
|
this.lblStatus.Location = new System.Drawing.Point(13, 260); // Скорректировано
|
||||||
|
this.lblStatus.Name = "lblStatus";
|
||||||
|
this.lblStatus.Size = new System.Drawing.Size(44, 13);
|
||||||
|
this.lblStatus.TabIndex = 9;
|
||||||
|
this.lblStatus.Text = "Статус:";
|
||||||
|
//
|
||||||
|
// cmbStores
|
||||||
|
//
|
||||||
|
this.cmbStores.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
|
this.cmbStores.FormattingEnabled = true;
|
||||||
|
this.cmbStores.Location = new System.Drawing.Point(88, 24);
|
||||||
|
this.cmbStores.Name = "cmbStores";
|
||||||
|
this.cmbStores.Size = new System.Drawing.Size(176, 21);
|
||||||
|
this.cmbStores.TabIndex = 0;
|
||||||
|
this.cmbStores.SelectedIndexChanged += new System.EventHandler(this.cmbStores_SelectedIndexChanged);
|
||||||
|
//
|
||||||
|
// btnManageStores
|
||||||
|
//
|
||||||
|
this.btnManageStores.Location = new System.Drawing.Point(270, 23);
|
||||||
|
this.btnManageStores.Name = "btnManageStores";
|
||||||
|
this.btnManageStores.Size = new System.Drawing.Size(118, 23);
|
||||||
|
this.btnManageStores.TabIndex = 1;
|
||||||
|
this.btnManageStores.Text = "Упр. магазинами...";
|
||||||
|
this.btnManageStores.UseVisualStyleBackColor = true;
|
||||||
|
this.btnManageStores.Click += new System.EventHandler(this.btnManageStores_Click);
|
||||||
|
//
|
||||||
|
// labelStore
|
||||||
|
//
|
||||||
|
this.labelStore.AutoSize = true;
|
||||||
|
this.labelStore.Location = new System.Drawing.Point(12, 27);
|
||||||
|
this.labelStore.Name = "labelStore";
|
||||||
|
this.labelStore.Size = new System.Drawing.Size(54, 13);
|
||||||
|
this.labelStore.TabIndex = 15;
|
||||||
|
this.labelStore.Text = "Магазин:";
|
||||||
|
//
|
||||||
|
// btnPageSetup
|
||||||
|
// *** Новая кнопка Настройки принтера ***
|
||||||
|
this.btnPageSetup.Location = new System.Drawing.Point(270, 53);
|
||||||
|
this.btnPageSetup.Name = "btnPageSetup";
|
||||||
|
this.btnPageSetup.Size = new System.Drawing.Size(118, 23);
|
||||||
|
this.btnPageSetup.TabIndex = 2; // Изменен TabIndex
|
||||||
|
this.btnPageSetup.Text = "Настройка принтера";
|
||||||
|
this.btnPageSetup.UseVisualStyleBackColor = true;
|
||||||
|
this.btnPageSetup.Click += new System.EventHandler(this.btnPageSetup_Click);
|
||||||
|
//
|
||||||
|
// pageSetupDialog1
|
||||||
|
// *** Диалог настройки страницы ***
|
||||||
|
this.pageSetupDialog1 = new System.Windows.Forms.PageSetupDialog();
|
||||||
|
this.pageSetupDialog1.EnableMetric = true;
|
||||||
|
//
|
||||||
|
// Form1
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.ClientSize = new System.Drawing.Size(404, 288); // Скорректирован размер
|
||||||
|
this.Controls.Add(this.btnPageSetup); // Добавлена кнопка
|
||||||
|
this.Controls.Add(this.labelStore);
|
||||||
|
this.Controls.Add(this.btnManageStores);
|
||||||
|
this.Controls.Add(this.cmbStores);
|
||||||
|
this.Controls.Add(this.lblStatus);
|
||||||
|
this.Controls.Add(this.btnPrintLabel);
|
||||||
|
this.Controls.Add(this.lblProductBarcode);
|
||||||
|
this.Controls.Add(this.lblProductSku);
|
||||||
|
this.Controls.Add(this.lblProductName);
|
||||||
|
this.Controls.Add(this.btnGetData);
|
||||||
|
this.Controls.Add(this.txtOfferId);
|
||||||
|
this.Controls.Add(this.label3);
|
||||||
|
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||||
|
this.MaximizeBox = false;
|
||||||
|
this.Name = "Form1";
|
||||||
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||||
|
this.Text = "Генератор внутренних этикеток Ozon";
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
this.PerformLayout();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private System.Windows.Forms.Label label3;
|
||||||
|
private System.Windows.Forms.TextBox txtOfferId;
|
||||||
|
private System.Windows.Forms.Button btnGetData;
|
||||||
|
private System.Windows.Forms.Label lblProductName;
|
||||||
|
private System.Windows.Forms.Label lblProductSku;
|
||||||
|
private System.Windows.Forms.Label lblProductBarcode;
|
||||||
|
private System.Windows.Forms.Button btnPrintLabel;
|
||||||
|
private System.Windows.Forms.Label lblStatus;
|
||||||
|
private System.Windows.Forms.ComboBox cmbStores;
|
||||||
|
private System.Windows.Forms.Button btnManageStores;
|
||||||
|
private System.Windows.Forms.Label labelStore;
|
||||||
|
private System.Windows.Forms.Button btnPageSetup; // Добавлено
|
||||||
|
private System.Windows.Forms.PageSetupDialog pageSetupDialog1; // Добавлено
|
||||||
|
}
|
||||||
|
}
|
500
Form1.cs
Normal file
500
Form1.cs
Normal file
@ -0,0 +1,500 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Printing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Security.Cryptography; // Для шифрования/дешифрования
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using SKLADm.Properties; // Для доступа к Settings.Default
|
||||||
|
using SKLADm;
|
||||||
|
using ZXing;
|
||||||
|
using ZXing.Common;
|
||||||
|
using ZXing.Windows.Compatibility;
|
||||||
|
|
||||||
|
namespace OzonInternalLabelPrinter // Убедитесь, что это ваше пространство имен
|
||||||
|
{
|
||||||
|
public partial class Form1 : Form
|
||||||
|
{
|
||||||
|
private HttpClient _httpClient;
|
||||||
|
// Bitmap больше не нужен как поле класса
|
||||||
|
// private Bitmap _labelBitmap;
|
||||||
|
private string _currentProductName;
|
||||||
|
private string _currentSku;
|
||||||
|
private string _currentBarcode;
|
||||||
|
private List<OzonStore> _availableStores;
|
||||||
|
// Поле для хранения экземпляра документа между настройкой и печатью
|
||||||
|
private PrintDocument _printDocForSetup; // Используем для PageSetup и Print
|
||||||
|
|
||||||
|
// Конструктор формы
|
||||||
|
public Form1()
|
||||||
|
{
|
||||||
|
InitializeComponent(); // Инициализирует компоненты из ДИЗАЙНЕРА
|
||||||
|
InitializeHttpClient();
|
||||||
|
// Инициализируем PrintDocument один раз
|
||||||
|
_printDocForSetup = new PrintDocument();
|
||||||
|
// Устанавливаем обработчик печати один раз
|
||||||
|
_printDocForSetup.PrintPage += new PrintPageEventHandler(pd_PrintPage);
|
||||||
|
// Загружаем магазины при запуске ПОСЛЕ инициализации _printDocForSetup
|
||||||
|
LoadStoresToComboBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Инициализация HTTP клиента
|
||||||
|
private void InitializeHttpClient()
|
||||||
|
{
|
||||||
|
_httpClient = new HttpClient
|
||||||
|
{
|
||||||
|
BaseAddress = new Uri("https://api-seller.ozon.ru/")
|
||||||
|
};
|
||||||
|
_httpClient.DefaultRequestHeaders.Accept.Clear();
|
||||||
|
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Логика работы с магазинами и ключами ---
|
||||||
|
|
||||||
|
private static readonly byte[] s_entropy = null; // Энтропия для шифрования
|
||||||
|
|
||||||
|
// Дешифрование Api-Key
|
||||||
|
private string DecryptApiKey(string encryptedKeyBase64)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(encryptedKeyBase64)) return string.Empty;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] encryptedBytes = Convert.FromBase64String(encryptedKeyBase64);
|
||||||
|
byte[] decryptedBytes = ProtectedData.Unprotect(encryptedBytes, s_entropy, DataProtectionScope.CurrentUser);
|
||||||
|
return Encoding.UTF8.GetString(decryptedBytes);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine($"Ошибка дешифрования ключа: {ex.Message}");
|
||||||
|
MessageBox.Show($"Не удалось дешифровать Api-Key для магазина '{cmbStores.Text}'. Возможно, настройки повреждены или созданы под другим пользователем.\n\nОшибка: {ex.Message}",
|
||||||
|
"Ошибка ключа", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Загрузка магазинов из настроек в ComboBox
|
||||||
|
private void LoadStoresToComboBox()
|
||||||
|
{
|
||||||
|
string json = Settings.Default.SavedStoresJson;
|
||||||
|
_availableStores = new List<OzonStore>();
|
||||||
|
if (!string.IsNullOrEmpty(json))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_availableStores = JsonConvert.DeserializeObject<List<OzonStore>>(json) ?? new List<OzonStore>();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Ошибка загрузки списка магазинов: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
_availableStores = new List<OzonStore>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmbStores.DataSource = null;
|
||||||
|
cmbStores.DataSource = _availableStores;
|
||||||
|
cmbStores.DisplayMember = "StoreName";
|
||||||
|
|
||||||
|
bool storesExist = _availableStores.Any();
|
||||||
|
cmbStores.Enabled = storesExist;
|
||||||
|
txtOfferId.Enabled = storesExist;
|
||||||
|
btnPageSetup.Enabled = storesExist; // Включаем настройку, если есть магазины
|
||||||
|
// Кнопка GetData включится при вводе артикула
|
||||||
|
|
||||||
|
if (storesExist)
|
||||||
|
{
|
||||||
|
cmbStores.SelectedIndex = 0;
|
||||||
|
// Установим принтер по умолчанию для _printDocForSetup, если возможно
|
||||||
|
TrySetDefaultPrinterForDocument();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmbStores.SelectedIndex = -1;
|
||||||
|
// Показываем сообщение, если нужно
|
||||||
|
// MessageBox.Show("Нет сохраненных магазинов...", "Внимание", MessageBoxButtons.OK, Information);
|
||||||
|
}
|
||||||
|
ResetProductData();
|
||||||
|
// Обновляем состояние кнопки GetData после загрузки
|
||||||
|
txtOfferId_TextChanged(txtOfferId, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Попытка установить принтер по умолчанию для PrintDocument
|
||||||
|
private void TrySetDefaultPrinterForDocument()
|
||||||
|
{
|
||||||
|
string thermalPrinterName = "Xprinter XP-365B"; // Или другое имя по умолчанию
|
||||||
|
foreach (string printerName in PrinterSettings.InstalledPrinters)
|
||||||
|
{
|
||||||
|
if (printerName.Equals(thermalPrinterName, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_printDocForSetup.PrinterSettings.PrinterName = printerName;
|
||||||
|
System.Diagnostics.Debug.WriteLine($"Принтер по умолчанию '{printerName}' установлен для PrintDocument.");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine($"Ошибка установки принтера по умолчанию '{printerName}': {ex.Message}");
|
||||||
|
}
|
||||||
|
return; // Выходим после нахождения
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.Diagnostics.Debug.WriteLine($"Принтер по умолчанию '{thermalPrinterName}' не найден.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Обработчики событий UI ---
|
||||||
|
|
||||||
|
private void btnManageStores_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
using (FormManageStores manageForm = new FormManageStores())
|
||||||
|
{
|
||||||
|
manageForm.ShowDialog(this);
|
||||||
|
LoadStoresToComboBox(); // Перезагружаем список
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cmbStores_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
ResetProductData();
|
||||||
|
txtOfferId_TextChanged(txtOfferId, EventArgs.Empty); // Обновляем состояние кнопки GetData
|
||||||
|
// Можно попробовать обновить принтер по умолчанию для _printDocForSetup,
|
||||||
|
// если у разных магазинов могут быть разные принтеры (но это усложнит логику)
|
||||||
|
}
|
||||||
|
|
||||||
|
private void txtOfferId_TextChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
btnGetData.Enabled = cmbStores.SelectedItem != null && !string.IsNullOrEmpty(txtOfferId.Text.Trim());
|
||||||
|
if (string.IsNullOrEmpty(txtOfferId.Text.Trim()))
|
||||||
|
{
|
||||||
|
ResetProductData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Кнопка "Настройка принтера" ---
|
||||||
|
private void btnPageSetup_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
// Убедимся, что принтер в _printDocForSetup актуален (если не нашли Xprinter при запуске,
|
||||||
|
// или если у пользователя несколько принтеров)
|
||||||
|
if (!PrinterSettings.InstalledPrinters.Cast<string>().Contains(_printDocForSetup.PrinterSettings.PrinterName))
|
||||||
|
{
|
||||||
|
// Если текущий принтер недоступен, сбрасываем на принтер по умолчанию Windows
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_printDocForSetup.PrinterSettings = new PrinterSettings(); // Сброс на настройки по умолчанию
|
||||||
|
System.Diagnostics.Debug.WriteLine("Текущий принтер в PrintDocument был недоступен, сброшен на принтер по умолчанию Windows.");
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
pageSetupDialog1.Document = _printDocForSetup; // Связываем диалог с нашим PrintDocument
|
||||||
|
pageSetupDialog1.MinMargins = new Margins(0, 0, 0, 0); // Минимальные поля
|
||||||
|
pageSetupDialog1.AllowMargins = true; // Разрешаем менять поля
|
||||||
|
pageSetupDialog1.AllowOrientation = false; // Запрещаем менять ориентацию
|
||||||
|
pageSetupDialog1.AllowPaper = true; // Разрешаем менять размер бумаги
|
||||||
|
pageSetupDialog1.AllowPrinter = true; // Разрешаем выбирать другой принтер
|
||||||
|
|
||||||
|
if (pageSetupDialog1.ShowDialog(this) == DialogResult.OK)
|
||||||
|
{
|
||||||
|
// Настройки применились к _printDocForSetup
|
||||||
|
lblStatus.Text = "Настройки принтера применены.";
|
||||||
|
System.Diagnostics.Debug.WriteLine($"PageSetupDialog OK: New PaperSize={_printDocForSetup.DefaultPageSettings.PaperSize.PaperName}, Printer={_printDocForSetup.PrinterSettings.PrinterName}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lblStatus.Text = "Настройка принтера отменена.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Получение данных из API ---
|
||||||
|
private async void btnGetData_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
OzonStore selectedStore = cmbStores.SelectedItem as OzonStore;
|
||||||
|
if (selectedStore == null) { MessageBox.Show("Выберите магазин.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; }
|
||||||
|
|
||||||
|
string clientId = selectedStore.ClientId;
|
||||||
|
string apiKey = DecryptApiKey(selectedStore.EncryptedApiKey);
|
||||||
|
if (apiKey == null) { lblStatus.Text = "Ошибка ключа API."; return; }
|
||||||
|
|
||||||
|
string rawOfferId = txtOfferId.Text.Trim();
|
||||||
|
if (string.IsNullOrEmpty(rawOfferId)) { MessageBox.Show("Введите Артикул.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; }
|
||||||
|
|
||||||
|
string offerId = Regex.Replace(rawOfferId, @"[^a-zA-Zа-яА-Я0-9_-]", "");
|
||||||
|
if (string.IsNullOrEmpty(offerId)) { MessageBox.Show("Артикул некорректен.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; }
|
||||||
|
if (offerId != rawOfferId) { txtOfferId.Text = offerId; }
|
||||||
|
|
||||||
|
ResetProductData();
|
||||||
|
lblStatus.Text = "Запрос данных...";
|
||||||
|
Application.DoEvents();
|
||||||
|
|
||||||
|
_httpClient.DefaultRequestHeaders.Remove("Client-Id");
|
||||||
|
_httpClient.DefaultRequestHeaders.Remove("Api-Key");
|
||||||
|
_httpClient.DefaultRequestHeaders.Add("Client-Id", clientId);
|
||||||
|
_httpClient.DefaultRequestHeaders.Add("Api-Key", apiKey);
|
||||||
|
|
||||||
|
string responseBody = string.Empty;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var requestData = new { offer_id = new[] { offerId } };
|
||||||
|
var jsonRequest = JsonConvert.SerializeObject(requestData);
|
||||||
|
var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
HttpResponseMessage response = await _httpClient.PostAsync("/v3/product/info/list", content);
|
||||||
|
responseBody = await response.Content.ReadAsStringAsync();
|
||||||
|
System.Diagnostics.Debug.WriteLine($"API Response ({response.StatusCode}): {responseBody}");
|
||||||
|
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
JObject jsonResponse = JObject.Parse(responseBody);
|
||||||
|
JToken itemsArray = jsonResponse["items"];
|
||||||
|
|
||||||
|
if (itemsArray != null && itemsArray.Type == JTokenType.Array && itemsArray.HasValues)
|
||||||
|
{
|
||||||
|
JToken firstItem = itemsArray[0];
|
||||||
|
if (firstItem != null)
|
||||||
|
{
|
||||||
|
_currentProductName = firstItem["name"]?.ToString() ?? "N/A";
|
||||||
|
_currentSku = firstItem["offer_id"]?.ToString() ?? offerId;
|
||||||
|
_currentBarcode = firstItem["barcode"]?.ToString();
|
||||||
|
if (string.IsNullOrEmpty(_currentBarcode))
|
||||||
|
{
|
||||||
|
JToken barcodesToken = firstItem["barcodes"];
|
||||||
|
if (barcodesToken != null && barcodesToken.Type == JTokenType.Array && barcodesToken.HasValues)
|
||||||
|
{ _currentBarcode = barcodesToken.First?.ToString(); }
|
||||||
|
}
|
||||||
|
_currentBarcode = _currentBarcode ?? "N/A";
|
||||||
|
|
||||||
|
GenerateLabelPreview(); // Обновляем UI и включаем кнопку печати
|
||||||
|
}
|
||||||
|
else { HandleApiError("Нет данных о товаре в ответе.", responseBody); }
|
||||||
|
}
|
||||||
|
else { HandleApiError("Ответ API не содержит списка товаров.", responseBody); }
|
||||||
|
}
|
||||||
|
else { HandleApiError($"Ошибка API: {response.StatusCode}", responseBody); }
|
||||||
|
}
|
||||||
|
catch (JsonReaderException jsonEx) { MessageBox.Show($"Ошибка JSON: {jsonEx.Message}\n{responseBody}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); ResetProductData(); }
|
||||||
|
catch (HttpRequestException httpEx) { MessageBox.Show($"Ошибка сети: {httpEx.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); ResetProductData(); }
|
||||||
|
catch (Exception ex) { MessageBox.Show($"Ошибка: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); ResetProductData(); }
|
||||||
|
finally { apiKey = null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обработка ошибок API
|
||||||
|
private void HandleApiError(string messagePrefix, string responseBody)
|
||||||
|
{
|
||||||
|
string errorMessage = $"{messagePrefix}";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
JObject errorJson = JObject.Parse(responseBody);
|
||||||
|
string ozonError = errorJson["message"]?.ToString() ?? errorJson["error"]?["message"]?.ToString();
|
||||||
|
errorMessage = string.IsNullOrEmpty(ozonError) ? $"{messagePrefix}\n{responseBody}" : $"{messagePrefix}\n{ozonError}";
|
||||||
|
}
|
||||||
|
catch { errorMessage = $"{messagePrefix}\n{responseBody}"; }
|
||||||
|
|
||||||
|
MessageBox.Show(errorMessage, "Ошибка API Ozon", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
lblStatus.Text = "Ошибка API.";
|
||||||
|
ResetProductData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сброс данных о товаре и состояния UI
|
||||||
|
private void ResetProductData()
|
||||||
|
{
|
||||||
|
_currentProductName = null;
|
||||||
|
_currentSku = null;
|
||||||
|
_currentBarcode = null;
|
||||||
|
lblProductName.Text = "Название:";
|
||||||
|
lblProductSku.Text = "Артикул:";
|
||||||
|
lblProductBarcode.Text = "Штрихкод:";
|
||||||
|
// Очищаем превью, если оно есть
|
||||||
|
if (this.Controls.ContainsKey("picLabelPreview"))
|
||||||
|
(this.Controls["picLabelPreview"] as PictureBox).Image = null;
|
||||||
|
btnPrintLabel.Enabled = false;
|
||||||
|
// lblStatus.Text = "Статус:";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Генерация (только обновление UI)
|
||||||
|
private void GenerateLabelPreview()
|
||||||
|
{
|
||||||
|
bool dataAvailable = !string.IsNullOrEmpty(_currentSku) &&
|
||||||
|
!string.IsNullOrEmpty(_currentProductName) &&
|
||||||
|
!string.IsNullOrEmpty(_currentBarcode) &&
|
||||||
|
_currentBarcode != "N/A";
|
||||||
|
if (!dataAvailable) { ResetProductData(); return; }
|
||||||
|
|
||||||
|
lblProductName.Text = $"Название: {_currentProductName}";
|
||||||
|
lblProductSku.Text = $"Артикул: {_currentSku}";
|
||||||
|
lblProductBarcode.Text = $"Штрихкод: {_currentBarcode}";
|
||||||
|
|
||||||
|
// Очистка превью, если оно есть
|
||||||
|
if (this.Controls.ContainsKey("picLabelPreview"))
|
||||||
|
(this.Controls["picLabelPreview"] as PictureBox).Image = null;
|
||||||
|
|
||||||
|
btnPrintLabel.Enabled = true;
|
||||||
|
lblStatus.Text = "Данные получены, готово к печати.";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --- Печать ---
|
||||||
|
|
||||||
|
// Кнопка "Печать этикетки"
|
||||||
|
private void btnPrintLabel_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(_currentSku) || string.IsNullOrEmpty(_currentProductName) || string.IsNullOrEmpty(_currentBarcode) || _currentBarcode == "N/A")
|
||||||
|
{
|
||||||
|
MessageBox.Show("Нет данных для печати.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintDialog printDialog = new PrintDialog();
|
||||||
|
printDialog.Document = _printDocForSetup; // Используем настроенный документ
|
||||||
|
printDialog.AllowSomePages = false;
|
||||||
|
printDialog.AllowSelection = false;
|
||||||
|
printDialog.UseEXDialog = true;
|
||||||
|
|
||||||
|
if (printDialog.ShowDialog(this) == DialogResult.OK)
|
||||||
|
{
|
||||||
|
// _printDocForSetup уже содержит принтер и настройки страницы, выбранные в PrintDialog или PageSetupDialog
|
||||||
|
// Переустанавливаем поля на случай, если PrintDialog их сбросил
|
||||||
|
_printDocForSetup.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
|
||||||
|
_printDocForSetup.OriginAtMargins = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
lblStatus.Text = $"Печать на {_printDocForSetup.PrinterSettings.PrinterName}...";
|
||||||
|
_printDocForSetup.Print(); // Печатаем с текущими настройками
|
||||||
|
lblStatus.Text = "Отправлено на печать.";
|
||||||
|
}
|
||||||
|
catch (InvalidPrinterException)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Ошибка: Принтер '{_printDocForSetup.PrinterSettings.PrinterName}' недоступен или не найден.\nПроверьте подключение или выберите другой принтер в настройках.", "Ошибка принтера", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
lblStatus.Text = "Ошибка принтера.";
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Ошибка печати: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
lblStatus.Text = "Ошибка печати.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { lblStatus.Text = "Печать отменена."; }
|
||||||
|
|
||||||
|
printDialog.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод отрисовки страницы для печати (динамический)
|
||||||
|
private void pd_PrintPage(object sender, PrintPageEventArgs e)
|
||||||
|
{
|
||||||
|
// Проверка данных
|
||||||
|
if (string.IsNullOrEmpty(_currentSku) || string.IsNullOrEmpty(_currentProductName) || string.IsNullOrEmpty(_currentBarcode) || _currentBarcode == "N/A")
|
||||||
|
{ System.Diagnostics.Debug.WriteLine("PrintPage ABORTED - Missing data!"); e.Cancel = true; return; }
|
||||||
|
|
||||||
|
Graphics g = e.Graphics;
|
||||||
|
// Получаем РЕАЛЬНЫЕ границы печатаемой области в единицах Graphics (обычно сотые дюйма)
|
||||||
|
// Не PageBounds, а PrintableArea! PageBounds - это физический размер листа.
|
||||||
|
RectangleF printArea = e.PageSettings.PrintableArea;
|
||||||
|
|
||||||
|
// Отступы от КРАЕВ ПЕЧАТАЕМОЙ ОБЛАСТИ (в единицах Graphics)
|
||||||
|
// Подбирайте эти значения, чтобы получить рамку внутри печатаемой зоны
|
||||||
|
float marginX = 5 * g.DpiX / 100f; // Пример: 5/100 дюйма -> в единицах Graphics
|
||||||
|
float marginY = 3 * g.DpiY / 100f; // Пример: 3/100 дюйма -> в единицах Graphics
|
||||||
|
|
||||||
|
// Область для рисования контента внутри отступов
|
||||||
|
float drawableX = printArea.Left + marginX;
|
||||||
|
float drawableY = printArea.Top + marginY;
|
||||||
|
float drawableWidth = printArea.Width - (marginX * 2);
|
||||||
|
float drawableHeight = printArea.Height - (marginY * 2);
|
||||||
|
float currentY = drawableY; // Текущая позиция по Y
|
||||||
|
|
||||||
|
// Проверка на валидность области
|
||||||
|
if (drawableWidth <= 0 || drawableHeight <= 0) { System.Diagnostics.Debug.WriteLine("PrintPage ABORTED - Invalid drawable area!"); e.Cancel = true; return; }
|
||||||
|
|
||||||
|
System.Diagnostics.Debug.WriteLine("--- Printing Page (Dynamic) ---");
|
||||||
|
System.Diagnostics.Debug.WriteLine($"Paper: {e.PageSettings.PaperSize.PaperName} ({e.PageSettings.PaperSize.Width}x{e.PageSettings.PaperSize.Height}) hund.inch");
|
||||||
|
System.Diagnostics.Debug.WriteLine($"PrintableArea ({g.PageUnit}): X={printArea.X:F2}, Y={printArea.Y:F2}, W={printArea.Width:F2}, H={printArea.Height:F2}");
|
||||||
|
System.Diagnostics.Debug.WriteLine($"Drawable Area ({g.PageUnit}): X={drawableX:F2}, Y={drawableY:F2}, W={drawableWidth:F2}, H={drawableHeight:F2}");
|
||||||
|
|
||||||
|
// Шрифты (размер в пунктах)
|
||||||
|
float baseFontSizePoints = 6f; // Базовый размер, можно менять
|
||||||
|
Font titleFont = new Font("Arial", baseFontSizePoints + 1, FontStyle.Bold);
|
||||||
|
Font regularFont = new Font("Arial", baseFontSizePoints);
|
||||||
|
Font barcodeTextFont = new Font("Arial", baseFontSizePoints - 1);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// --- Рисуем Название ---
|
||||||
|
string productName = _currentProductName ?? "N/A";
|
||||||
|
SizeF titleSize = g.MeasureString(productName, titleFont, (int)drawableWidth);
|
||||||
|
// Ограничиваем высоту, чтобы поместилось остальное
|
||||||
|
float maxTitleHeight = drawableHeight * 0.3f;
|
||||||
|
float actualTitleHeight = Math.Min(titleSize.Height, maxTitleHeight);
|
||||||
|
g.DrawString(productName, titleFont, Brushes.Black, new RectangleF(drawableX, currentY, drawableWidth, actualTitleHeight));
|
||||||
|
currentY += actualTitleHeight + (2 * g.DpiY / 72f); // Отступ 2 пункта
|
||||||
|
|
||||||
|
// --- Рисуем Артикул ---
|
||||||
|
string skuText = $"Артикул: {_currentSku ?? "N/A"}";
|
||||||
|
SizeF skuSize = g.MeasureString(skuText, regularFont, (int)drawableWidth);
|
||||||
|
if (currentY + skuSize.Height < printArea.Bottom - marginY - 15 * 100f / g.DpiY) // Оставляем ~15px под ШК + текст
|
||||||
|
{
|
||||||
|
g.DrawString(skuText, regularFont, Brushes.Black, drawableX, currentY);
|
||||||
|
currentY += skuSize.Height + (3 * g.DpiY / 72f); // Отступ 3 пункта
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Рисуем Штрихкод ---
|
||||||
|
float remainingHeight = (printArea.Bottom - marginY) - currentY; // Оставшаяся высота
|
||||||
|
if (remainingHeight > 15 * 100f / g.DpiY) // Если осталось хотя бы ~15px
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// --- Расчет размеров ШК ---
|
||||||
|
float barcodeTextHeight = g.MeasureString(_currentBarcode, barcodeTextFont).Height;
|
||||||
|
float barcodePrintHeight = Math.Max(10 * 100f / g.DpiY, remainingHeight - barcodeTextHeight - (2 * g.DpiY / 72f)); // Вычитаем текст и отступ
|
||||||
|
float barcodePrintWidth = drawableWidth * 0.98f;
|
||||||
|
|
||||||
|
int barcodePixelHeight = (int)(barcodePrintHeight * g.DpiY / 100f);
|
||||||
|
int barcodePixelWidth = (int)(barcodePrintWidth * g.DpiX / 100f);
|
||||||
|
if (barcodePixelHeight < 10 || barcodePixelWidth < 40) throw new Exception("Слишком мало места для ШК.");
|
||||||
|
|
||||||
|
BarcodeFormat barcodeFormat = BarcodeFormat.CODE_128;
|
||||||
|
// ... (определение barcodeFormat) ...
|
||||||
|
if (_currentBarcode.Length == 13 && long.TryParse(_currentBarcode, out _)) barcodeFormat = BarcodeFormat.EAN_13;
|
||||||
|
else if (_currentBarcode.Length == 8 && long.TryParse(_currentBarcode, out _)) barcodeFormat = BarcodeFormat.EAN_8;
|
||||||
|
|
||||||
|
var barcodeWriter = new ZXing.Windows.Compatibility.BarcodeWriter { Format = barcodeFormat, Options = new EncodingOptions { Height = barcodePixelHeight, Width = barcodePixelWidth, PureBarcode = true, Margin = 1 } };
|
||||||
|
|
||||||
|
using (var barcodeBitmap = barcodeWriter.Write(_currentBarcode))
|
||||||
|
{
|
||||||
|
float barcodeX = drawableX + (drawableWidth - barcodePrintWidth) / 2.0f; // Центрируем
|
||||||
|
g.DrawImage(barcodeBitmap, barcodeX, currentY, barcodePrintWidth, barcodePrintHeight);
|
||||||
|
currentY += barcodePrintHeight + (1 * g.DpiY / 72f); // Отступ 1 пункт
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Рисуем текст ШК ---
|
||||||
|
SizeF barcodeTextSize = g.MeasureString(_currentBarcode, barcodeTextFont);
|
||||||
|
if (currentY + barcodeTextSize.Height <= printArea.Bottom - marginY)
|
||||||
|
{
|
||||||
|
float textX = drawableX + (drawableWidth - barcodeTextSize.Width) / 2.0f; // Центрируем
|
||||||
|
g.DrawString(_currentBarcode, barcodeTextFont, Brushes.Black, textX, currentY);
|
||||||
|
}
|
||||||
|
else { System.Diagnostics.Debug.WriteLine("SKIPPING Barcode text - no space"); }
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception exBarcode)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine($"Error drawing barcode: {exBarcode.Message}");
|
||||||
|
g.DrawString("Ошибка ШК", regularFont, Brushes.Red, drawableX, currentY); // Рисуем ошибку вместо ШК
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { System.Diagnostics.Debug.WriteLine("SKIPPING Barcode - not enough vertical space"); }
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception exDraw) { System.Diagnostics.Debug.WriteLine($"Error drawing page: {exDraw}"); }
|
||||||
|
finally { titleFont.Dispose(); regularFont.Dispose(); barcodeTextFont.Dispose(); }
|
||||||
|
|
||||||
|
e.HasMorePages = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // Конец класса Form1
|
||||||
|
} // Конец namespace
|
120
Form1.resx
Normal file
120
Form1.resx
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
201
FormManageStores.Designer.cs
generated
Normal file
201
FormManageStores.Designer.cs
generated
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
namespace SKLADm
|
||||||
|
{
|
||||||
|
partial class FormManageStores
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.lstStores = new System.Windows.Forms.ListBox();
|
||||||
|
this.label1 = new System.Windows.Forms.Label();
|
||||||
|
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||||
|
this.btnAddStore = new System.Windows.Forms.Button();
|
||||||
|
this.txtEditApiKey = new System.Windows.Forms.TextBox();
|
||||||
|
this.label4 = new System.Windows.Forms.Label();
|
||||||
|
this.txtEditClientId = new System.Windows.Forms.TextBox();
|
||||||
|
this.label3 = new System.Windows.Forms.Label();
|
||||||
|
this.txtStoreName = new System.Windows.Forms.TextBox();
|
||||||
|
this.label2 = new System.Windows.Forms.Label();
|
||||||
|
this.btnDeleteStore = new System.Windows.Forms.Button();
|
||||||
|
this.btnClose = new System.Windows.Forms.Button();
|
||||||
|
this.groupBox1.SuspendLayout();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// lstStores
|
||||||
|
//
|
||||||
|
this.lstStores.FormattingEnabled = true;
|
||||||
|
this.lstStores.Location = new System.Drawing.Point(12, 25);
|
||||||
|
this.lstStores.Name = "lstStores";
|
||||||
|
this.lstStores.Size = new System.Drawing.Size(188, 199); // Adjust height as needed
|
||||||
|
this.lstStores.TabIndex = 0;
|
||||||
|
// Add event handler if you want to display details on selection:
|
||||||
|
// this.lstStores.SelectedIndexChanged += new System.EventHandler(this.lstStores_SelectedIndexChanged);
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
this.label1.AutoSize = true;
|
||||||
|
this.label1.Location = new System.Drawing.Point(12, 9);
|
||||||
|
this.label1.Name = "label1";
|
||||||
|
this.label1.Size = new System.Drawing.Size(121, 13);
|
||||||
|
this.label1.TabIndex = 1;
|
||||||
|
this.label1.Text = "Сохраненные магазины:";
|
||||||
|
//
|
||||||
|
// groupBox1
|
||||||
|
//
|
||||||
|
this.groupBox1.Controls.Add(this.btnAddStore);
|
||||||
|
this.groupBox1.Controls.Add(this.txtEditApiKey);
|
||||||
|
this.groupBox1.Controls.Add(this.label4);
|
||||||
|
this.groupBox1.Controls.Add(this.txtEditClientId);
|
||||||
|
this.groupBox1.Controls.Add(this.label3);
|
||||||
|
this.groupBox1.Controls.Add(this.txtStoreName);
|
||||||
|
this.groupBox1.Controls.Add(this.label2);
|
||||||
|
this.groupBox1.Location = new System.Drawing.Point(219, 25);
|
||||||
|
this.groupBox1.Name = "groupBox1";
|
||||||
|
this.groupBox1.Size = new System.Drawing.Size(303, 155); // Adjust size as needed
|
||||||
|
this.groupBox1.TabIndex = 2;
|
||||||
|
this.groupBox1.TabStop = false;
|
||||||
|
this.groupBox1.Text = "Добавить новый магазин";
|
||||||
|
//
|
||||||
|
// btnAddStore
|
||||||
|
//
|
||||||
|
this.btnAddStore.Location = new System.Drawing.Point(196, 118);
|
||||||
|
this.btnAddStore.Name = "btnAddStore";
|
||||||
|
this.btnAddStore.Size = new System.Drawing.Size(97, 23);
|
||||||
|
this.btnAddStore.TabIndex = 6;
|
||||||
|
this.btnAddStore.Text = "Добавить";
|
||||||
|
this.btnAddStore.UseVisualStyleBackColor = true;
|
||||||
|
this.btnAddStore.Click += new System.EventHandler(this.btnAddStore_Click);
|
||||||
|
//
|
||||||
|
// txtEditApiKey
|
||||||
|
//
|
||||||
|
this.txtEditApiKey.Location = new System.Drawing.Point(74, 86);
|
||||||
|
this.txtEditApiKey.Name = "txtEditApiKey";
|
||||||
|
this.txtEditApiKey.PasswordChar = '*';
|
||||||
|
this.txtEditApiKey.Size = new System.Drawing.Size(219, 20);
|
||||||
|
this.txtEditApiKey.TabIndex = 5;
|
||||||
|
//
|
||||||
|
// label4
|
||||||
|
//
|
||||||
|
this.label4.AutoSize = true;
|
||||||
|
this.label4.Location = new System.Drawing.Point(16, 89);
|
||||||
|
this.label4.Name = "label4";
|
||||||
|
this.label4.Size = new System.Drawing.Size(48, 13);
|
||||||
|
this.label4.TabIndex = 4;
|
||||||
|
this.label4.Text = "Api-Key:";
|
||||||
|
//
|
||||||
|
// txtEditClientId
|
||||||
|
//
|
||||||
|
this.txtEditClientId.Location = new System.Drawing.Point(74, 57);
|
||||||
|
this.txtEditClientId.Name = "txtEditClientId";
|
||||||
|
this.txtEditClientId.Size = new System.Drawing.Size(219, 20);
|
||||||
|
this.txtEditClientId.TabIndex = 3;
|
||||||
|
//
|
||||||
|
// label3
|
||||||
|
//
|
||||||
|
this.label3.AutoSize = true;
|
||||||
|
this.label3.Location = new System.Drawing.Point(16, 60);
|
||||||
|
this.label3.Name = "label3";
|
||||||
|
this.label3.Size = new System.Drawing.Size(50, 13);
|
||||||
|
this.label3.TabIndex = 2;
|
||||||
|
this.label3.Text = "Client ID:";
|
||||||
|
//
|
||||||
|
// txtStoreName
|
||||||
|
//
|
||||||
|
this.txtStoreName.Location = new System.Drawing.Point(74, 28);
|
||||||
|
this.txtStoreName.Name = "txtStoreName";
|
||||||
|
this.txtStoreName.Size = new System.Drawing.Size(219, 20);
|
||||||
|
this.txtStoreName.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// label2
|
||||||
|
//
|
||||||
|
this.label2.AutoSize = true;
|
||||||
|
this.label2.Location = new System.Drawing.Point(16, 31);
|
||||||
|
this.label2.Name = "label2";
|
||||||
|
this.label2.Size = new System.Drawing.Size(60, 13);
|
||||||
|
this.label2.TabIndex = 0;
|
||||||
|
this.label2.Text = "Название:";
|
||||||
|
//
|
||||||
|
// btnDeleteStore
|
||||||
|
//
|
||||||
|
this.btnDeleteStore.Location = new System.Drawing.Point(12, 230); // Position below listbox
|
||||||
|
this.btnDeleteStore.Name = "btnDeleteStore";
|
||||||
|
this.btnDeleteStore.Size = new System.Drawing.Size(188, 23);
|
||||||
|
this.btnDeleteStore.TabIndex = 3;
|
||||||
|
this.btnDeleteStore.Text = "Удалить выбранный";
|
||||||
|
this.btnDeleteStore.UseVisualStyleBackColor = true;
|
||||||
|
this.btnDeleteStore.Click += new System.EventHandler(this.btnDeleteStore_Click);
|
||||||
|
//
|
||||||
|
// btnClose
|
||||||
|
//
|
||||||
|
this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel; // Makes Esc close the form
|
||||||
|
this.btnClose.Location = new System.Drawing.Point(447, 230); // Position bottom right
|
||||||
|
this.btnClose.Name = "btnClose";
|
||||||
|
this.btnClose.Size = new System.Drawing.Size(75, 23);
|
||||||
|
this.btnClose.TabIndex = 4;
|
||||||
|
this.btnClose.Text = "Закрыть";
|
||||||
|
this.btnClose.UseVisualStyleBackColor = true;
|
||||||
|
this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
|
||||||
|
//
|
||||||
|
// FormManageStores
|
||||||
|
//
|
||||||
|
this.AcceptButton = this.btnAddStore; // Enter in groupbox adds store
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.CancelButton = this.btnClose; // Esc closes form
|
||||||
|
this.ClientSize = new System.Drawing.Size(534, 267); // Adjust size as needed
|
||||||
|
this.Controls.Add(this.btnClose);
|
||||||
|
this.Controls.Add(this.btnDeleteStore);
|
||||||
|
this.Controls.Add(this.groupBox1);
|
||||||
|
this.Controls.Add(this.label1);
|
||||||
|
this.Controls.Add(this.lstStores);
|
||||||
|
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; // Prevent resizing
|
||||||
|
this.MaximizeBox = false;
|
||||||
|
this.MinimizeBox = false;
|
||||||
|
this.Name = "FormManageStores";
|
||||||
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; // Center over Form1
|
||||||
|
this.Text = "Управление магазинами Ozon";
|
||||||
|
this.groupBox1.ResumeLayout(false);
|
||||||
|
this.groupBox1.PerformLayout();
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
this.PerformLayout();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private System.Windows.Forms.ListBox lstStores;
|
||||||
|
private System.Windows.Forms.Label label1;
|
||||||
|
private System.Windows.Forms.GroupBox groupBox1;
|
||||||
|
private System.Windows.Forms.Button btnAddStore;
|
||||||
|
private System.Windows.Forms.TextBox txtEditApiKey;
|
||||||
|
private System.Windows.Forms.Label label4;
|
||||||
|
private System.Windows.Forms.TextBox txtEditClientId;
|
||||||
|
private System.Windows.Forms.Label label3;
|
||||||
|
private System.Windows.Forms.TextBox txtStoreName;
|
||||||
|
private System.Windows.Forms.Label label2;
|
||||||
|
private System.Windows.Forms.Button btnDeleteStore;
|
||||||
|
private System.Windows.Forms.Button btnClose;
|
||||||
|
}
|
||||||
|
}
|
150
FormManageStores.cs
Normal file
150
FormManageStores.cs
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using OzonInternalLabelPrinter; // Добавляем пространство имен для OzonStore
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Cryptography; // Для ProtectedData
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace SKLADm
|
||||||
|
{
|
||||||
|
public partial class FormManageStores : Form
|
||||||
|
{
|
||||||
|
private List<OzonStore> _stores;
|
||||||
|
// Энтропия для шифрования (можно оставить null или использовать свой секрет)
|
||||||
|
private static readonly byte[] s_entropy = null; // Или Encoding.UTF8.GetBytes("MyOptionalEntropy");
|
||||||
|
|
||||||
|
public FormManageStores()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
LoadStoresToListBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Шифрование Api-Key ---
|
||||||
|
private string EncryptApiKey(string apiKey)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(apiKey)) return string.Empty;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] apiKeyBytes = Encoding.UTF8.GetBytes(apiKey);
|
||||||
|
byte[] encryptedBytes = ProtectedData.Protect(apiKeyBytes, s_entropy, DataProtectionScope.CurrentUser);
|
||||||
|
return Convert.ToBase64String(encryptedBytes);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Ошибка шифрования ключа: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return null; // Возвращаем null при ошибке
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Загрузка магазинов из настроек ---
|
||||||
|
private void LoadStoresToListBox()
|
||||||
|
{
|
||||||
|
string json = Properties.Settings.Default.SavedStoresJson;
|
||||||
|
_stores = new List<OzonStore>();
|
||||||
|
if (!string.IsNullOrEmpty(json))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_stores = JsonConvert.DeserializeObject<List<OzonStore>>(json) ?? new List<OzonStore>();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Ошибка загрузки списка магазинов: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
_stores = new List<OzonStore>(); // Создаем пустой список при ошибке
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UpdateListBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Сохранение магазинов в настройки ---
|
||||||
|
private void SaveStores()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string json = JsonConvert.SerializeObject(_stores, Formatting.Indented);
|
||||||
|
Properties.Settings.Default.SavedStoresJson = json;
|
||||||
|
Properties.Settings.Default.Save();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Ошибка сохранения списка магазинов: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Обновление ListBox ---
|
||||||
|
private void UpdateListBox()
|
||||||
|
{
|
||||||
|
lstStores.DataSource = null; // Сначала отвязываем источник
|
||||||
|
lstStores.DataSource = _stores; // Привязываем обновленный список
|
||||||
|
lstStores.DisplayMember = "StoreName"; // Отображаем имя
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Кнопка "Добавить магазин" ---
|
||||||
|
private void btnAddStore_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
string storeName = txtStoreName.Text.Trim();
|
||||||
|
string clientId = txtEditClientId.Text.Trim();
|
||||||
|
string apiKey = txtEditApiKey.Text.Trim(); // Берем ключ как есть
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(storeName) || string.IsNullOrEmpty(clientId) || string.IsNullOrEmpty(apiKey))
|
||||||
|
{
|
||||||
|
MessageBox.Show("Пожалуйста, заполните все поля: Название, Client ID, Api-Key.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверяем, нет ли уже магазина с таким именем
|
||||||
|
if (_stores.Any(s => s.StoreName.Equals(storeName, StringComparison.OrdinalIgnoreCase)))
|
||||||
|
{
|
||||||
|
MessageBox.Show("Магазин с таким названием уже существует.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Шифруем ключ
|
||||||
|
string encryptedKey = EncryptApiKey(apiKey);
|
||||||
|
if (encryptedKey == null) // Если шифрование не удалось
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Создаем и добавляем магазин
|
||||||
|
OzonStore newStore = new OzonStore(storeName, clientId, encryptedKey);
|
||||||
|
_stores.Add(newStore);
|
||||||
|
|
||||||
|
// Сохраняем и обновляем список
|
||||||
|
SaveStores();
|
||||||
|
UpdateListBox();
|
||||||
|
|
||||||
|
// Очищаем поля ввода
|
||||||
|
txtStoreName.Clear();
|
||||||
|
txtEditClientId.Clear();
|
||||||
|
txtEditApiKey.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Кнопка "Удалить выбранный" (Опционально) ---
|
||||||
|
private void btnDeleteStore_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (lstStores.SelectedItem is OzonStore selectedStore)
|
||||||
|
{
|
||||||
|
if (MessageBox.Show($"Вы уверены, что хотите удалить магазин '{selectedStore.StoreName}'?", "Подтверждение", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
|
||||||
|
{
|
||||||
|
_stores.Remove(selectedStore);
|
||||||
|
SaveStores();
|
||||||
|
UpdateListBox();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Выберите магазин для удаления.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Кнопка "Закрыть" ---
|
||||||
|
private void btnClose_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
this.DialogResult = DialogResult.OK; // Указываем, что форма закрыта штатно
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
FormManageStores.resx
Normal file
120
FormManageStores.resx
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
28
OzonStore.cs
Normal file
28
OzonStore.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace OzonInternalLabelPrinter
|
||||||
|
{
|
||||||
|
[Serializable] // Важно для возможной сериализации в будущем, хотя с JSON необязательно
|
||||||
|
public class OzonStore
|
||||||
|
{
|
||||||
|
public string StoreName { get; set; } // Имя, которое видит пользователь
|
||||||
|
public string ClientId { get; set; }
|
||||||
|
public string EncryptedApiKey { get; set; } // Храним ЗАШИФРОВАННЫЙ ключ
|
||||||
|
|
||||||
|
// Конструктор для удобства
|
||||||
|
public OzonStore(string name, string clientId, string encryptedKey)
|
||||||
|
{
|
||||||
|
StoreName = name;
|
||||||
|
ClientId = clientId;
|
||||||
|
EncryptedApiKey = encryptedKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OzonStore() { } // Пустой конструктор для сериализации
|
||||||
|
|
||||||
|
// Переопределяем ToString, чтобы в ComboBox отображалось имя
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return StoreName ?? "Без имени";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
Program.cs
Normal file
23
Program.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using OzonInternalLabelPrinter; // Добавляем директиву using для пространства имен с Form1
|
||||||
|
|
||||||
|
namespace SKLADm
|
||||||
|
{
|
||||||
|
internal static class Program
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Главная точка входа для приложения.
|
||||||
|
/// </summary>
|
||||||
|
[STAThread]
|
||||||
|
static void Main()
|
||||||
|
{
|
||||||
|
Application.EnableVisualStyles();
|
||||||
|
Application.SetCompatibleTextRenderingDefault(false);
|
||||||
|
Application.Run(new Form1());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
33
Properties/AssemblyInfo.cs
Normal file
33
Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// Общие сведения об этой сборке предоставляются следующим набором
|
||||||
|
// набора атрибутов. Измените значения этих атрибутов для изменения сведений,
|
||||||
|
// связанных со сборкой.
|
||||||
|
[assembly: AssemblyTitle("SKLADm")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("SKLADm")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2025")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми
|
||||||
|
// для компонентов COM. Если необходимо обратиться к типу в этой сборке через
|
||||||
|
// COM, следует установить атрибут ComVisible в TRUE для этого типа.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
|
||||||
|
[assembly: Guid("17f6818e-f645-43c4-a25a-eab41e5e1be6")]
|
||||||
|
|
||||||
|
// Сведения о версии сборки состоят из указанных ниже четырех значений:
|
||||||
|
//
|
||||||
|
// Основной номер версии
|
||||||
|
// Дополнительный номер версии
|
||||||
|
// Номер сборки
|
||||||
|
// Редакция
|
||||||
|
//
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
71
Properties/Resources.Designer.cs
generated
Normal file
71
Properties/Resources.Designer.cs
generated
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// Этот код создан программным средством.
|
||||||
|
// Версия среды выполнения: 4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Изменения в этом файле могут привести к неправильному поведению и будут утрачены, если
|
||||||
|
// код создан повторно.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace SKLADm.Properties
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Класс ресурсов со строгим типом для поиска локализованных строк и пр.
|
||||||
|
/// </summary>
|
||||||
|
// Этот класс был автоматически создан при помощи StronglyTypedResourceBuilder
|
||||||
|
// класс с помощью таких средств, как ResGen или Visual Studio.
|
||||||
|
// Для добавления или удаления члена измените файл .ResX, а затем перезапустите ResGen
|
||||||
|
// с параметром /str или заново постройте свой VS-проект.
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class Resources
|
||||||
|
{
|
||||||
|
|
||||||
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal Resources()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Возврат кэшированного экземпляра ResourceManager, используемого этим классом.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Resources.ResourceManager ResourceManager
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if ((resourceMan == null))
|
||||||
|
{
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SKLADm.Properties.Resources", typeof(Resources).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Переопределяет свойство CurrentUICulture текущего потока для всех
|
||||||
|
/// подстановки ресурсов с помощью этого класса ресурсов со строгим типом.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Globalization.CultureInfo Culture
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
117
Properties/Resources.resx
Normal file
117
Properties/Resources.resx
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
38
Properties/Settings.Designer.cs
generated
Normal file
38
Properties/Settings.Designer.cs
generated
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// Этот код создан программой.
|
||||||
|
// Исполняемая версия:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
|
||||||
|
// повторной генерации кода.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace SKLADm.Properties {
|
||||||
|
|
||||||
|
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.13.0.0")]
|
||||||
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||||
|
|
||||||
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||||
|
|
||||||
|
public static Settings Default {
|
||||||
|
get {
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||||
|
public string SavedStoresJson {
|
||||||
|
get {
|
||||||
|
return ((string)(this["SavedStoresJson"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["SavedStoresJson"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
Properties/Settings.settings
Normal file
9
Properties/Settings.settings
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="SKLADm.Properties" GeneratedClassName="Settings">
|
||||||
|
<Profiles />
|
||||||
|
<Settings>
|
||||||
|
<Setting Name="SavedStoresJson" Type="System.String" Scope="User">
|
||||||
|
<Value Profile="(Default)" />
|
||||||
|
</Setting>
|
||||||
|
</Settings>
|
||||||
|
</SettingsFile>
|
122
SKLADm.csproj
Normal file
122
SKLADm.csproj
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{17F6818E-F645-43C4-A25A-EAB41E5E1BE6}</ProjectGuid>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<RootNamespace>SKLADm</RootNamespace>
|
||||||
|
<AssemblyName>SKLADm</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
<NuGetPackageImportStamp>
|
||||||
|
</NuGetPackageImportStamp>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Drawing.Common, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\System.Drawing.Common.8.0.12\lib\net462\System.Drawing.Common.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Security" />
|
||||||
|
<Reference Include="System.Security.Cryptography.ProtectedData, Version=9.0.0.4, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\System.Security.Cryptography.ProtectedData.9.0.4\lib\net462\System.Security.Cryptography.ProtectedData.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Deployment" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="zxing, Version=0.16.10.0, Culture=neutral, PublicKeyToken=4e88037ac681fe60, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\ZXing.Net.0.16.10\lib\net461\zxing.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="zxing.presentation, Version=0.16.10.0, Culture=neutral, PublicKeyToken=4e88037ac681fe60, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\ZXing.Net.0.16.10\lib\net461\zxing.presentation.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="ZXing.Windows.Compatibility, Version=0.16.13.0, Culture=neutral, PublicKeyToken=4e88037ac681fe60, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\ZXing.Net.Bindings.Windows.Compatibility.0.16.13\lib\netstandard2.0\ZXing.Windows.Compatibility.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Form1.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Form1.Designer.cs">
|
||||||
|
<DependentUpon>Form1.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="FormManageStores.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="FormManageStores.Designer.cs">
|
||||||
|
<DependentUpon>FormManageStores.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="OzonStore.cs" />
|
||||||
|
<Compile Include="Program.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<EmbeddedResource Include="Form1.resx">
|
||||||
|
<DependentUpon>Form1.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="FormManageStores.resx">
|
||||||
|
<DependentUpon>FormManageStores.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Properties\Resources.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<None Include="packages.config" />
|
||||||
|
<None Include="Properties\Settings.settings">
|
||||||
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
<Compile Include="Properties\Settings.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="App.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<Import Project="packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets" Condition="Exists('packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets')" />
|
||||||
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ErrorText>Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}.</ErrorText>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Error Condition="!Exists('packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\NETStandard.Library.2.0.3\build\netstandard2.0\NETStandard.Library.targets'))" />
|
||||||
|
</Target>
|
||||||
|
</Project>
|
25
SKLADm.sln
Normal file
25
SKLADm.sln
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.13.35913.81 d17.13
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SKLADm", "SKLADm.csproj", "{17F6818E-F645-43C4-A25A-EAB41E5E1BE6}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{17F6818E-F645-43C4-A25A-EAB41E5E1BE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{17F6818E-F645-43C4-A25A-EAB41E5E1BE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{17F6818E-F645-43C4-A25A-EAB41E5E1BE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{17F6818E-F645-43C4-A25A-EAB41E5E1BE6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {58FC063D-E3B8-421B-BCB0-0349A0C4DCDB}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
10
packages.config
Normal file
10
packages.config
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net462" />
|
||||||
|
<package id="NETStandard.Library" version="2.0.3" targetFramework="net462" />
|
||||||
|
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net462" />
|
||||||
|
<package id="System.Drawing.Common" version="8.0.12" targetFramework="net462" />
|
||||||
|
<package id="System.Security.Cryptography.ProtectedData" version="9.0.4" targetFramework="net462" />
|
||||||
|
<package id="ZXing.Net" version="0.16.10" targetFramework="net462" />
|
||||||
|
<package id="ZXing.Net.Bindings.Windows.Compatibility" version="0.16.13" targetFramework="net462" />
|
||||||
|
</packages>
|
Loading…
x
Reference in New Issue
Block a user