From bf464b04a6af521e9aadd9a6c7e87b030a008e17 Mon Sep 17 00:00:00 2001 From: XerolySkinner Date: Tue, 11 Nov 2025 16:51:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=A0=87=E5=87=86=E5=BA=93UD?= =?UTF-8?q?P=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ramitta/CryptoHelper.cs | 287 ++++++++++++++++++------- Ramitta/Excel.cs | 2 +- Ramitta/Ramitta.cs | 23 +- Ramitta/Ramitta.csproj | 1 + Ramitta/SerialPortHandler.cs | 200 ++++++++++++++++++ template/MainWindow.xaml | 6 +- template/MainWindow.xaml.cs | 168 ++++----------- template/device.cs | 397 +---------------------------------- template/template.csproj | 2 +- 9 files changed, 479 insertions(+), 607 deletions(-) create mode 100644 Ramitta/SerialPortHandler.cs diff --git a/Ramitta/CryptoHelper.cs b/Ramitta/CryptoHelper.cs index d789e39..57ecbcd 100644 --- a/Ramitta/CryptoHelper.cs +++ b/Ramitta/CryptoHelper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; @@ -11,39 +12,143 @@ namespace Ramitta.lib public class CryptoHelper { /// - /// 生成RSA密钥对 + /// 通过OpenSSH格式私钥计算公钥(Base64格式) /// - /// 密钥长度(通常为2048、4096) - /// 包含公钥和私钥的元组 - public static (string publicKey, string privateKey) GenerateKeyPair(int keySize = 2048) - { - try - { - using (var rsa = RSA.Create(keySize)) - { - string publicKey = rsa.ToXmlString(false); - string privateKey = rsa.ToXmlString(true); - - return (publicKey, privateKey); - } - } - catch (Exception ex) - { - MessageBox.Show($"密钥生成失败: {ex.Message}"); - return (null, null); - } - } - - /// - /// 使用私钥对数据进行签名 - /// - public static string? SignData(string data, string privateKey) + /// OpenSSH格式的Base64私钥(不带PEM头尾) + /// Base64格式的公钥,失败返回null + public static string? GetPublicKeyFromPrivate(string openSshPrivateKey) { try { using (var rsa = RSA.Create()) { - rsa.FromXmlString(privateKey); + // 解析OpenSSH私钥格式 + ImportOpenSshPrivateKey(rsa, openSshPrivateKey); + + // 导出公钥为Base64 + byte[] publicKeyBytes = rsa.ExportRSAPublicKey(); + return Convert.ToBase64String(publicKeyBytes); + } + } + catch (Exception ex) + { + MessageBox.Show($"从私钥提取公钥失败: {ex.Message}"); + return null; + } + } + + /// + /// 导入OpenSSH格式的私钥(纯Base64编码) + /// + private static void ImportOpenSshPrivateKey(RSA rsa, string openSshBase64) + { + byte[] keyData = Convert.FromBase64String(openSshBase64); + + using (var reader = new BinaryReader(new MemoryStream(keyData))) + { + // 读取魔术字 + var magic = reader.ReadBytes(15); + string magicString = Encoding.ASCII.GetString(magic); + if (magicString != "openssh-key-v1\0") + throw new FormatException("无效的OpenSSH私钥格式"); + + // 读取加密信息 + var cipherName = ReadLengthPrefixedString(reader); + var kdfName = ReadLengthPrefixedString(reader); + var kdfOptions = ReadLengthPrefixedData(reader); + + // 检查是否加密 + if (cipherName != "none" || kdfName != "none") + throw new FormatException("不支持加密的OpenSSH私钥"); + + // 读取密钥数量 + var keyCount = ReadUInt32BigEndian(reader); + if (keyCount != 1) + throw new FormatException("不支持多个密钥"); + + // 读取公钥(跳过) + var publicKey = ReadLengthPrefixedData(reader); + + // 读取私钥数据 + var privateKeyData = ReadLengthPrefixedData(reader); + + // 解析私钥数据 + using (var privateReader = new BinaryReader(new MemoryStream(privateKeyData))) + { + // 检查字节序标记 + var check1 = privateReader.ReadUInt32(); + var check2 = privateReader.ReadUInt32(); + if (check1 != check2) + throw new FormatException("私钥检查值不匹配"); + + // 读取密钥类型 + var keyType = ReadLengthPrefixedString(privateReader); + if (keyType != "ssh-rsa") + throw new FormatException("非RSA密钥"); + + // 读取RSA参数 + var modulus = ReadLengthPrefixedData(privateReader); // n + var publicExponent = ReadLengthPrefixedData(privateReader); // e + var privateExponent = ReadLengthPrefixedData(privateReader); // d + var coefficient = ReadLengthPrefixedData(privateReader); // iqmp + var prime1 = ReadLengthPrefixedData(privateReader); // p + var prime2 = ReadLengthPrefixedData(privateReader); // q + + // 创建RSA参数并导入 + var rsaParameters = new RSAParameters + { + Modulus = modulus, + Exponent = publicExponent, + D = privateExponent, + P = prime1, + Q = prime2, + InverseQ = coefficient + }; + + rsa.ImportParameters(rsaParameters); + } + } + } + + /// + /// 读取长度前缀字符串 + /// + private static string ReadLengthPrefixedString(BinaryReader reader) + { + var data = ReadLengthPrefixedData(reader); + return Encoding.ASCII.GetString(data); + } + + /// + /// 读取长度前缀数据 + /// + private static byte[] ReadLengthPrefixedData(BinaryReader reader) + { + var length = ReadUInt32BigEndian(reader); + return reader.ReadBytes((int)length); + } + + /// + /// 以大端序读取uint32 + /// + private static uint ReadUInt32BigEndian(BinaryReader reader) + { + var data = reader.ReadBytes(4); + if (BitConverter.IsLittleEndian) + Array.Reverse(data); + return BitConverter.ToUInt32(data, 0); + } + + /// + /// 使用OpenSSH格式私钥对数据进行签名 + /// + public static string? SignDataWithOpenSsh(string data, string openSshPrivateKey) + { + try + { + using (var rsa = RSA.Create()) + { + ImportOpenSshPrivateKey(rsa, openSshPrivateKey); byte[] dataBytes = Encoding.UTF8.GetBytes(data); byte[] signature = rsa.SignData(dataBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); @@ -58,61 +163,15 @@ namespace Ramitta.lib } /// - /// 使用公钥验证签名 + /// 使用OpenSSH格式私钥解密数据 /// - public static bool? VerifySignature(string data, string signature, string publicKey) + public static string? DecryptWithOpenSsh(string encryptedData, string openSshPrivateKey) { try { using (var rsa = RSA.Create()) { - rsa.FromXmlString(publicKey); - - byte[] dataBytes = Encoding.UTF8.GetBytes(data); - byte[] signatureBytes = Convert.FromBase64String(signature); - - return rsa.VerifyData(dataBytes, signatureBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); - } - } - catch (Exception ex) - { - return false; - } - } - - /// - /// 使用公钥加密数据 - /// - public static string? Encrypt(string data, string publicKey) - { - try - { - using (var rsa = RSA.Create()) - { - rsa.FromXmlString(publicKey); - - byte[] dataBytes = Encoding.UTF8.GetBytes(data); - byte[] encryptedBytes = rsa.Encrypt(dataBytes, RSAEncryptionPadding.OaepSHA256); - - return Convert.ToBase64String(encryptedBytes); - } - } - catch (Exception ex) - { - return null; - } - } - - /// - /// 使用私钥解密数据 - /// - public static string? Decrypt(string encryptedData, string privateKey) - { - try - { - using (var rsa = RSA.Create()) - { - rsa.FromXmlString(privateKey); + ImportOpenSshPrivateKey(rsa, openSshPrivateKey); byte[] encryptedBytes = Convert.FromBase64String(encryptedData); byte[] decryptedBytes = rsa.Decrypt(encryptedBytes, RSAEncryptionPadding.OaepSHA256); @@ -125,5 +184,79 @@ namespace Ramitta.lib return null; } } + + /// + /// 获取OpenSSH格式私钥的密钥长度 + /// + public static int GetOpenSshKeySize(string openSshPrivateKey) + { + try + { + using (var rsa = RSA.Create()) + { + ImportOpenSshPrivateKey(rsa, openSshPrivateKey); + return rsa.KeySize; + } + } + catch (Exception ex) + { + MessageBox.Show($"获取密钥长度失败: {ex.Message}"); + return -1; + } + } + + // 其他原有方法保持不变... + public static (string publicKey, string privateKey) GenerateKeyPair(int keySize = 2048) + { + try + { + using (var rsa = RSA.Create(keySize)) + { + byte[] publicKeyBytes = rsa.ExportRSAPublicKey(); + byte[] privateKeyBytes = rsa.ExportRSAPrivateKey(); + + string publicKey = Convert.ToBase64String(publicKeyBytes); + string privateKey = Convert.ToBase64String(privateKeyBytes); + + return (publicKey, privateKey); + } + } + catch (Exception ex) + { + MessageBox.Show($"密钥生成失败: {ex.Message}"); + return (null, null); + } + } + + public static string? SignData(string data, string privateKey) + { + try + { + using (var rsa = RSA.Create()) + { + byte[] privateKeyBytes = Convert.FromBase64String(privateKey); + + try + { + rsa.ImportRSAPrivateKey(privateKeyBytes, out _); + } + catch + { + rsa.ImportPkcs8PrivateKey(privateKeyBytes, out _); + } + + byte[] dataBytes = Encoding.UTF8.GetBytes(data); + byte[] signature = rsa.SignData(dataBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + + return Convert.ToBase64String(signature); + } + } + catch (Exception ex) + { + return null; + } + } + + // 其他方法... } -} +} \ No newline at end of file diff --git a/Ramitta/Excel.cs b/Ramitta/Excel.cs index bda6ff6..a630795 100644 --- a/Ramitta/Excel.cs +++ b/Ramitta/Excel.cs @@ -7,7 +7,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Ramitta.Excellib +namespace Ramitta.lib { public static class Excel { diff --git a/Ramitta/Ramitta.cs b/Ramitta/Ramitta.cs index ef24e60..c9b1b5c 100644 --- a/Ramitta/Ramitta.cs +++ b/Ramitta/Ramitta.cs @@ -344,13 +344,32 @@ namespace Ramitta.lib #endregion // ͨ UDP Ϣ - public static void SendUdpMessage(string _serverIp, int _serverPort,string message) + public static void SendUdpMessage(string _serverIp, int _serverPort, string message) { try { using (UdpClient udpClient = new UdpClient()) { - IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(_serverIp), _serverPort); + IPEndPoint endPoint; + + // ԶʶȳԽΪIPַʧ + if (IPAddress.TryParse(_serverIp, out IPAddress ipAddress)) + { + // IPַ + endPoint = new IPEndPoint(ipAddress, _serverPort); + } + else + { + // DNS + IPAddress[] addresses = Dns.GetHostAddresses(_serverIp); + if (addresses.Length == 0) + { + Debug.WriteLine($"޷: {_serverIp}"); + return; + } + endPoint = new IPEndPoint(addresses[0], _serverPort); + } + byte[] messageBytes = Encoding.UTF8.GetBytes(message); udpClient.Send(messageBytes, messageBytes.Length, endPoint); } diff --git a/Ramitta/Ramitta.csproj b/Ramitta/Ramitta.csproj index 131c5dd..8b1f3e0 100644 --- a/Ramitta/Ramitta.csproj +++ b/Ramitta/Ramitta.csproj @@ -17,6 +17,7 @@ + diff --git a/Ramitta/SerialPortHandler.cs b/Ramitta/SerialPortHandler.cs new file mode 100644 index 0000000..a391926 --- /dev/null +++ b/Ramitta/SerialPortHandler.cs @@ -0,0 +1,200 @@ +using System; +using System.IO.Ports; +using System.Threading; + + +namespace Ramitta.lib +{ + + public class SerialPortHandler : IDisposable + { + private SerialPort _serialPort; + private bool _isConnected = false; + + // 串口连接状态事件 + public event Action ConnectionStatusChanged; + public event Action DataReceived; + public event Action ErrorOccurred; + + public SerialPortHandler() + { + _serialPort = new SerialPort(); + _serialPort.DataReceived += SerialPort_DataReceived; + _serialPort.ErrorReceived += SerialPort_ErrorReceived; + } + + /// + /// 获取可用的串口列表 + /// + public string[] GetAvailablePorts() + { + return SerialPort.GetPortNames(); + } + + /// + /// 连接串口 + /// + public bool Connect(string portName, int baudRate = 9600, Parity parity = Parity.None, + int dataBits = 8, StopBits stopBits = StopBits.One) + { + try + { + if (_isConnected) + Disconnect(); + + _serialPort.PortName = portName; + _serialPort.BaudRate = baudRate; + _serialPort.Parity = parity; + _serialPort.DataBits = dataBits; + _serialPort.StopBits = stopBits; + _serialPort.Handshake = Handshake.None; + _serialPort.ReadTimeout = 1000; + _serialPort.WriteTimeout = 1000; + + _serialPort.Open(); + _isConnected = true; + + ConnectionStatusChanged?.Invoke(true); + return true; + } + catch (Exception ex) + { + ErrorOccurred?.Invoke($"连接串口失败: {ex.Message}"); + return false; + } + } + + /// + /// 断开串口连接 + /// + public void Disconnect() + { + try + { + if (_serialPort.IsOpen) + { + _serialPort.Close(); + _isConnected = false; + ConnectionStatusChanged?.Invoke(false); + } + } + catch (Exception ex) + { + ErrorOccurred?.Invoke($"断开串口失败: {ex.Message}"); + } + } + + /// + /// 发送数据 + /// + public bool SendData(string data) + { + try + { + if (!_isConnected) + { + ErrorOccurred?.Invoke("串口未连接"); + return false; + } + + _serialPort.WriteLine(data); + return true; + } + catch (Exception ex) + { + ErrorOccurred?.Invoke($"发送数据失败: {ex.Message}"); + return false; + } + } + + /// + /// 发送字节数据 + /// + public bool SendBytes(byte[] data) + { + try + { + if (!_isConnected) + { + ErrorOccurred?.Invoke("串口未连接"); + return false; + } + + _serialPort.Write(data, 0, data.Length); + return true; + } + catch (Exception ex) + { + ErrorOccurred?.Invoke($"发送字节数据失败: {ex.Message}"); + return false; + } + } + + /// + /// 读取数据 + /// + public string ReadData() + { + try + { + if (!_isConnected) + { + ErrorOccurred?.Invoke("串口未连接"); + return string.Empty; + } + + return _serialPort.ReadExisting(); + } + catch (Exception ex) + { + ErrorOccurred?.Invoke($"读取数据失败: {ex.Message}"); + return string.Empty; + } + } + + /// + /// 获取连接状态 + /// + public bool IsConnected => _isConnected; + + /// + /// 获取串口信息 + /// + public string GetPortInfo() + { + if (!_isConnected) + return "串口未连接"; + + return $"{_serialPort.PortName} - {_serialPort.BaudRate}bps, {_serialPort.DataBits}数据位, {_serialPort.StopBits}停止位"; + } + + // 数据接收事件处理 + private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) + { + try + { + string data = _serialPort.ReadExisting(); + DataReceived?.Invoke(data); + } + catch (Exception ex) + { + ErrorOccurred?.Invoke($"数据接收错误: {ex.Message}"); + } + } + + // 错误接收事件处理 + private void SerialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e) + { + ErrorOccurred?.Invoke($"串口错误: {e.EventType}"); + } + + /// + /// 释放资源 + /// + public void Dispose() + { + Disconnect(); + _serialPort?.Dispose(); + } + } +} \ No newline at end of file diff --git a/template/MainWindow.xaml b/template/MainWindow.xaml index e37ce2c..abaa138 100644 --- a/template/MainWindow.xaml +++ b/template/MainWindow.xaml @@ -38,9 +38,9 @@ - - - + + + diff --git a/template/MainWindow.xaml.cs b/template/MainWindow.xaml.cs index cf1880d..360bece 100644 --- a/template/MainWindow.xaml.cs +++ b/template/MainWindow.xaml.cs @@ -30,164 +30,77 @@ using System.Windows.Shapes; using System.Windows.Threading; using System.Xml.Linq; -using static Ramitta.Excel; +using static Ramitta.lib.SerialPortHandler; +using static Ramitta.lib.Excel; using static Ramitta.lib.Basic; using static Ramitta.lib.CryptoHelper; using static Ramitta.SQLite; using static Ramitta.winDataGrid; + + namespace template { public partial class MainWindow : Window { - public class XlsxRows - { - public string 物号 { get; set; } - public string 名称描述 { get; set; } - public float 数量 { get; set; } - public List 标记 { get; set; } - public string 备注 { get; set; } - } - - static string? filePath; - #region 初始化MainWindow public MainWindow(StartupEventArgs e) { - Startupe = ParseCommandLineArgs(e.Args); InitializeComponent(); - if (Startupe.TryGetValue("getfile", out string filePath)) - { - MainWindow.filePath = filePath; - DebugBar(Debugtag, $"操作目标:{filePath}", 正常绿色); - } - else - { - DebugBar(Debugtag, $"未指定操作目标", 警告橙色); - } - - } #endregion - public static List EvaluateFormulaExample(string filePath, string? checkTitle = null) + private async void 增(object sender, RoutedEventArgs e) { + string filename = @"C:\Users\XerolySkinner\Desktop\identifier.sqlite"; + SQLite db = new SQLite($"Data Source={filename};Version=3;"); - IWorkbook workbook; - // 1. 根据文件扩展名创建正确的 Workbook 实例 - using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) + try { - if (System.IO.Path.GetExtension(filePath).ToLower() == ".xlsx") + // 构建查询语句和参数 + string query = "SELECT * FROM 屋檐屋面方管数 WHERE 型号 = \"M0\" AND 跨度 = 15"; + + // 执行查询 + List> results = db.SelectData(query); + + // 处理查询结果 + if (results != null && results.Count > 0) { - workbook = new XSSFWorkbook(fs); + // 遍历所有行 + foreach (var row in results) + { + // 遍历每行的所有列 + foreach (var column in row) + { + Debug.WriteLine($"{column.Key}: {column.Value}"); + } + Debug.WriteLine("---"); // 行分隔符 + } + + // 或者您可以根据需要处理数据,比如显示在界面上 + // 例如:dataGrid.ItemsSource = results; } else { - workbook = new HSSFWorkbook(fs); // 用于 .xls + Debug.WriteLine("未找到记录"); } } - // 2. 获取第一个工作表 - ISheet sheet = workbook.GetSheetAt(0); - - ISheet? sheetRelate = null; - if (workbook.NumberOfSheets > 1) + catch (Exception ex) { - sheetRelate = workbook.GetSheetAt(1); // 获取第二个工作表 - } - // 3. 公式表化 - if (sheetRelate != null) - { - Dictionary valueDictionary = new Dictionary(); - for (int i = 0; i <= sheetRelate.LastRowNum; i++) - { - IRow row = sheetRelate.GetRow(i); - if (row != null) - { - ICell keyCell = row.GetCell(0); - ICell valueCell = row.GetCell(1); - - if (keyCell != null && valueCell != null) - { - string key = keyCell.ToString(); - valueDictionary[key] = valueCell; // 存入字典 - } - } - } - valueDictionary["单元数"]?.SetCellValue(50); - } - - // 4. 遍历跳过行首 - List result= new List(); - for (int i = 1; i <= sheet.LastRowNum; i++) { - XlsxRows member = new(); - member.物号 = sheet.GetRow(i).GetCell(0)?.ToString() ?? ""; - member.名称描述 = sheet.GetRow(i).GetCell(1)?.ToString() ?? ""; - member.标记 = new(); - member.备注 = sheet.GetRow(i).GetCell(4)?.ToString() ?? ""; - try { - member.数量 = xlsxEvaluatorDouble( - workbook, - sheet.GetRow(i).GetCell(2)); - result.Add(member); - } - catch { - member.数量 = -1; - } - - } - - // 5. 关闭工作簿(如果不再需要) - workbook.Close(); - return result; - } - - public static float xlsxEvaluatorDouble(IWorkbook workbook,ICell cell) { - IFormulaEvaluator evaluator = workbook.GetCreationHelper().CreateFormulaEvaluator(); - // 5. 判断单元格类型是否为公式 - if (cell.CellType == CellType.Formula) - { - // 6. 计算公式并获取计算后的单元格值(CellValue) - CellValue evaluatedCellValue = evaluator.Evaluate(cell); - // 7. 根据计算结果的类型获取值 - switch (evaluatedCellValue.CellType) - { - case CellType.Numeric: - float numericValue = (float)(evaluatedCellValue.NumberValue); - return numericValue; - break; - case CellType.String: - string stringValue = evaluatedCellValue.StringValue; - break; - case CellType.Boolean: - bool boolValue = evaluatedCellValue.BooleanValue; - break; - case CellType.Error: - // 处理错误值 - Debug.WriteLine("公式计算错误"); - break; - default: - Debug.WriteLine("未知类型的公式结果"); - break; - } - } - else - { - return (float)cell.NumericCellValue; - } - throw new NotImplementedException("并非都是double返回值"); - } - - private async void 增(object sender, RoutedEventArgs e) - { - var ret=EvaluateFormulaExample(@"C:\Users\Xeroly\Desktop\newmagg.xlsx"); - - foreach (var cell in ret) { - Debug.WriteLine($"{cell.物号}->{cell.名称描述}:{cell.数量}"); + // 处理异常 + Debug.WriteLine($"查询失败: {ex.Message}"); } } private async void 改(object sender, RoutedEventArgs e) { + var mkshit = GenerateKeyPair(); + var privateKey = "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"; + privateKey=privateKey.Replace("\r",""); + privateKey = privateKey.Replace("\n", ""); + + string calculatedPublicKey = GetPublicKeyFromPrivate(privateKey); + } private async void 删(object? sender = null, RoutedEventArgs? e=null) @@ -202,7 +115,6 @@ namespace template private void 载入(object sender, RoutedEventArgs e) { - } private void 卸载(object sender, RoutedEventArgs e) diff --git a/template/device.cs b/template/device.cs index b978075..2f291af 100644 --- a/template/device.cs +++ b/template/device.cs @@ -1,6 +1,4 @@ -using MongoDB.Bson; -using MongoDB.Driver; -using NPOI.XSSF.UserModel; +using NPOI.XSSF.UserModel; using Ramitta; using System; using System.Collections; @@ -12,7 +10,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; -using static Ramitta.Excel; +using static Ramitta.lib.Excel; using static Ramitta.lib.Basic; @@ -20,323 +18,6 @@ namespace template { public partial class MainWindow { - Ramitta.Neo4jtool neo4jService = new Ramitta.Neo4jtool("bolt://localhost:7687", "neo4j", "AE1BC6D3"); - - public async void 数据升天计划neo4j() - { - await neo4jService.DeleteAllNodesAndRelationshipsAsync(); - - var 文件夹名单 = GetFilesAndDirectories(inputPath(null,null), true, - outputFormat: dir => Path.GetFileNameWithoutExtension(dir)); - - - foreach (var 文件夹 in 文件夹名单) - { - var 文件名单 = GetFilesAndDirectories(inputPath(null, null) + 文件夹, false, - outputFormat: dir => System.IO.Path.GetFileNameWithoutExtension(dir)); - - await neo4jService.CreateNodeAsync("文件夹", new Dictionary() { { "name", 文件夹 } },alway_create:true); - - foreach (var 文件 in 文件名单) - { - var name = Guid.NewGuid().ToString(); - var pair = new Dictionary() { - { "name", name },{ "文件夹",文件夹} }; - - if (文件夹.Contains("边墙沉重管") || - 文件夹.Contains("边墙基座固定") || - 文件夹.Contains("杂件")) - { - } - else - { - pair.Add("类型", Regex.Match(文件, @"([^-]+)").Groups[1].Value); - } - - if ( - 文件夹.Contains("边墙沉重管") || - 文件夹.Contains("承重柱") || - 文件夹.Contains("弧形拉伸杆") || - 文件夹.Contains("山墙侧柱套件") || - 文件夹.Contains("山墙沉重管") || - 文件夹.Contains("屋脊连接角") || - 文件夹.Contains("屋面方管") || - 文件夹.Contains("屋檐方管") || - 文件夹.Contains("斜梁") || - 文件夹.Contains("右悬挂管") || - 文件夹.Contains("左悬挂管")) - { - pair.Add("型号", Regex.Match(文件, @"^(?:[^-]+-){2}([^-\r\n]+)").Groups[1].Value); - } - - if (文件.Contains("跨度")) - { - pair.Add("跨度", Regex.Match(文件, @"跨度(\d+)").Groups[1].Value); - } - - if (文件.Contains("长度")) - { - pair.Add("长度", Regex.Match(文件, @"长度(\d+)").Groups[1].Value); - } - - if (文件.Contains("宽度")) - { - pair.Add("宽度", Regex.Match(文件, @"宽度(\d+)").Groups[1].Value); - } - - await neo4jService.CreateNodeAsync("文件", pair, alway_create: true); - await neo4jService.CreateRelationshipAsync("拥有", - "文件夹", new Dictionary { { "name", 文件夹 } }, - "文件", new Dictionary { { "name", name } }); - - } - } - } - - Func inputPath = (n, f) => - { - // 如果 n 和 f 都为空,返回文件路径的根目录 - if (string.IsNullOrEmpty(n) && string.IsNullOrEmpty(f)) - return @"C:\Users\Xeroly\Desktop\组件库\"; - - // 如果 n 为空,返回路径不包含文件夹 - if (string.IsNullOrEmpty(n)) - return @"C:\Users\Xeroly\Desktop\组件库\" + f + ".xlsx"; - - // 如果 f 为空,返回路径不包含文件名 - if (string.IsNullOrEmpty(f)) - return @"C:\Users\Xeroly\Desktop\组件库\" + n + @"\"; - - // 如果 n 和 f 都不为空,返回完整路径 - return @"C:\Users\Xeroly\Desktop\组件库\" + n + @"\" + f + ".xlsx"; - }; - Func outPath = (n) => @"C:\Users\Xeroly\Desktop\Outnm\" + n +".xlsx"; - - public void CreateXlsxMember( - Dictionary pair, - string? fileUUID = null, - Dictionary>? dict = null) - { - // 如果没有传入 fileUUID,使用pair中的"name"作为文件名 - if (fileUUID == null) - fileUUID = pair["name"].ToString(); - - // 创建一个新的工作簿 - var workbook = new XSSFWorkbook(); - var sheet1 = workbook.CreateSheet("data"); - var sheet2 = workbook.CreateSheet("info"); - var sheet3 = workbook.CreateSheet("link"); - - // 将字典pair内容竖着写入sheet2(即键在第一行,值在第二行) - int columnIndex = 0; - var headerRow = sheet2.CreateRow(0); // 第一行用作标题行(键) - var valueRow = sheet2.CreateRow(1); // 第二行用作数据行(值) - - foreach (var entry in pair) - { - // 将键写入第一行的相应单元格 - headerRow.CreateCell(columnIndex).SetCellValue(entry.Key); - - // 将值写入第二行的相应单元格 - valueRow.CreateCell(columnIndex).SetCellValue(entry.Value?.ToString() ?? ""); // 防止null值导致异常 - - columnIndex++; - } - - // 如果dict不为空,将其内容竖着写入sheet1 - if (dict != null && dict.Any()) - { - int rowIndex = 0; - - // 先写入表头(字典的键) - var dictHeaderRow = sheet1.CreateRow(rowIndex++); - int dictColumnIndex = 0; - foreach (var key in dict.Keys) - { - dictHeaderRow.CreateCell(dictColumnIndex++).SetCellValue(key); // 写入字典的键作为列名 - } - - // 写入每一列数据(将List的数据填充到各自的列) - int maxRows = dict.Values.Max(list => list.Count); // 获取最多的行数 - - for (int i = 0; i < maxRows; i++) - { - var row = sheet1.CreateRow(rowIndex++); - - int colIndex = 0; - foreach (var key in dict.Keys) - { - var list = dict[key]; - - // 如果list中有对应的项,写入,否则写入空字符串 - row.CreateCell(colIndex++).SetCellValue(i < list.Count ? list[i] : string.Empty); - } - } - } - - // 将数据写入到文件 - using (var fs = new FileStream(outPath(fileUUID), FileMode.Create, FileAccess.Write)) - { - workbook.Write(fs); - } - } - - - - public async void 表原核生物化() { - - var 文件夹名单 = GetFilesAndDirectories(inputPath(null, null), true, - outputFormat: dir => Path.GetFileNameWithoutExtension(dir)); - - foreach (var 文件夹 in 文件夹名单) - { - var 文件名单 = GetFilesAndDirectories(inputPath(null, null) + 文件夹, false, - outputFormat: dir => Path.GetFileNameWithoutExtension(dir)); - - foreach (var 文件 in 文件名单) - { - var name = Guid.NewGuid().ToString(); - var pair = new Dictionary() { - {"name", name },{"文件夹", 文件夹 } }; - - if (文件夹.Contains("边墙沉重管") || - 文件夹.Contains("边墙基座固定") || - 文件夹.Contains("杂件")) - { - } - else - { - pair.Add("类型", Regex.Match(文件, @"([^-]+)").Groups[1].Value); - } - - if ( - 文件夹.Contains("边墙沉重管") || - 文件夹.Contains("承重柱") || - 文件夹.Contains("弧形拉伸杆") || - 文件夹.Contains("山墙侧柱套件") || - 文件夹.Contains("山墙沉重管") || - 文件夹.Contains("屋脊连接角") || - 文件夹.Contains("屋面方管") || - 文件夹.Contains("屋檐方管") || - 文件夹.Contains("斜梁") || - 文件夹.Contains("右悬挂管") || - 文件夹.Contains("左悬挂管")) - { - pair.Add("型号", Regex.Match(文件, @"^(?:[^-]+-){2}([^-\r\n]+)").Groups[1].Value); - } - - if (文件.Contains("跨度")) - { - pair.Add("跨度", Regex.Match(文件, @"跨度(\d+)").Groups[1].Value); - } - - if (文件.Contains("长度")) - { - pair.Add("长度", Regex.Match(文件, @"长度(\d+)").Groups[1].Value); - } - - if (文件.Contains("宽度")) - { - pair.Add("宽度", Regex.Match(文件, @"宽度(\d+)").Groups[1].Value); - } - if (文件.Contains("边高")) - { - pair.Add("边高", Regex.Match(文件, @"边高(\d+)").Groups[1].Value); - } - - Dictionary> dict = - ReadExcelAsDictCol(inputPath(文件夹, 文件),headerInit:new List() { - "料号","名称","数量","标志","备注" }); - - // 删除每个列表中第一个元素(如果列表不为空) - foreach (var key in dict.Keys.ToList()) // 使用ToList()来避免修改集合时的枚举问题 - { - if (dict[key].Any()) - { - dict[key].RemoveAt(0); // 删除列表中的第一个元素 - } - } - - CreateXlsxMember(pair, - dict:dict); - } - } - } - - public async void 新建关系(Dictionary pair, Dictionary> dict,string tap,string rela="属于") { - if (pair.ContainsKey(tap)) - { - await neo4jService.CreateNodeAsync(tap, new Dictionary() { - { "name", tap} }); - - await neo4jService.CreateRelationshipAsync(rela, - tap, new Dictionary { { "name", tap } }, - "文件", new Dictionary { { "name", dict["name"][0] } }, - relationshipProperties: - new Dictionary{ { "value", dict[tap][0] } }); - } - } - - public async void 库表升天() { - await neo4jService.DeleteAllNodesAndRelationshipsAsync(); - var 文件夹路径 = @"C:\Users\Xeroly\Desktop\Outnm\"; - - var 文件名单 = GetFilesAndDirectories( - 文件夹路径,false, - outputFormat: dir => Path.GetFileNameWithoutExtension(dir)); - - foreach (var 文件 in 文件名单) { - var dict = ReadExcelAsDictCol(文件夹路径+文件+".xlsx",sheetName:"info"); - - // 创建新的字典pair - var pair = new Dictionary(); - - // 遍历dict,将每个key对应的第一个value添加到新的pair字典中 - foreach (var entry in dict) - { - if (entry.Value.Any()) // 确保每个列表至少有一个元素 - { - pair.Add(entry.Key, entry.Value[0]); // 只取第一个元素 - } - } - - await neo4jService.CreateNodeAsync("文件夹", new Dictionary() { - { "name", dict["文件夹"][0] } }); - - await neo4jService.CreateNodeAsync("文件", pair); - - - - await neo4jService.CreateRelationshipAsync("拥有", - "文件夹", new Dictionary { { "name", dict["文件夹"][0] } }, - "文件", new Dictionary { { "name", dict["name"][0] } }); - - - 新建关系(pair, dict, "跨度", "跨度"); - 新建关系(pair, dict, "宽度","宽度"); - 新建关系(pair, dict, "长度","长度"); - 新建关系(pair, dict, "型号","型号"); - 新建关系(pair, dict, "边高", "边高"); - - var dictdata = ReadExcelAsDictRow(文件夹路径 + 文件 + ".xlsx", sheetName: "data",headerInit: - new List() { "料号","名称","数量","标志","备注"}); - - dictdata.RemoveAt(0); // 移除列表中的第一个字典 - - foreach (var row in dictdata) { - await neo4jService.CreateNodeAsync("品物", new Dictionary() { - { "name", row["料号"] },{"名称",row["名称"] } }); - - await neo4jService.CreateRelationshipAsync("数量", - "文件", new Dictionary { { "name", dict["name"][0] } }, - "品物", new Dictionary { { "name", row["料号"] } }, - relationshipProperties: - new Dictionary { { "数量", row["数量"] } }); - } - - } - } - public async void 数据升天计划sqlite() { string filename = @"C:\Users\Xeroly\Desktop\琦亚\Kia.db"; SQLite db = new SQLite($"Data Source={filename};Version=3;"); @@ -456,79 +137,5 @@ namespace template } } - public async void 数据升天计划mongodb() - { - var 文件夹名单 = GetFilesAndDirectories(inputPath(null, null), true, - outputFormat: dir => Path.GetFileNameWithoutExtension(dir)); - - foreach (var 文件夹 in 文件夹名单) - { - var 文件名单 = GetFilesAndDirectories(inputPath(null, null) + 文件夹, false, - outputFormat: dir => System.IO.Path.GetFileNameWithoutExtension(dir)); - /* - // 使用示例 - var mongoDB = new MongoDB_interface( - "mongodb://localhost:27017", - "XerolySkinner", - 文件夹); - */ - foreach (var 文件 in 文件名单) - { - var name = Guid.NewGuid().ToString(); - var pair = new Dictionary() { - { "name", name },{ "文件夹",文件夹} }; - - if (文件夹.Contains("边墙沉重管") || - 文件夹.Contains("边墙基座固定") || - 文件夹.Contains("杂件")) - { - } - else - { - pair.Add("类型", Regex.Match(文件, @"([^-]+)").Groups[1].Value); - } - - if ( - 文件夹.Contains("边墙沉重管") || - 文件夹.Contains("承重柱") || - 文件夹.Contains("弧形拉伸杆") || - 文件夹.Contains("山墙侧柱套件") || - 文件夹.Contains("山墙沉重管") || - 文件夹.Contains("屋脊连接角") || - 文件夹.Contains("屋面方管") || - 文件夹.Contains("屋檐方管") || - 文件夹.Contains("斜梁") || - 文件夹.Contains("右悬挂管") || - 文件夹.Contains("左悬挂管")) - { - pair.Add("型号", Regex.Match(文件, @"^(?:[^-]+-){2}([^-\r\n]+)").Groups[1].Value); - } - - if (文件.Contains("跨度")) - { - pair.Add("跨度", Regex.Match(文件, @"跨度(\d+)").Groups[1].Value); - } - - if (文件.Contains("长度")) - { - pair.Add("长度", Regex.Match(文件, @"长度(\d+)").Groups[1].Value); - } - - if (文件.Contains("宽度")) - { - pair.Add("宽度", Regex.Match(文件, @"宽度(\d+)").Groups[1].Value); - } - - /* - await neo4jService.CreateNodeAsync("文件", pair, alway_create: true); - await neo4jService.CreateRelationshipAsync("拥有", - "文件夹", new Dictionary { { "name", 文件夹 } }, - "文件", new Dictionary { { "name", name } }); - */ - - } - } - } - } } diff --git a/template/template.csproj b/template/template.csproj index 7dc4d33..9dd63f2 100644 --- a/template/template.csproj +++ b/template/template.csproj @@ -12,8 +12,8 @@ - +