From 7d2b0422c8f2f4050c783518ba04588d33b73b46 Mon Sep 17 00:00:00 2001 From: ChenYi <296215406@outlook.com> Date: Mon, 3 Nov 2025 14:17:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=96=87=E4=BB=B6=E9=9D=9EUTF8=E7=BC=96=E7=A0=81?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- check_encoding.ps1 | 152 ++++++++++++++++++ host/JiShe.IoT.HttpApi.Host/Program.cs | 49 +++--- src/JiShe.IoT.Application/IoTAppService.cs | 2 + .../IoTApplicationModule.cs | 4 +- .../Data/IoTDbMigrationService.cs | 6 +- 5 files changed, 185 insertions(+), 28 deletions(-) create mode 100644 check_encoding.ps1 diff --git a/check_encoding.ps1 b/check_encoding.ps1 new file mode 100644 index 0000000..6333748 --- /dev/null +++ b/check_encoding.ps1 @@ -0,0 +1,152 @@ +# PowerShell 脚本:检查文件编码是否为 UTF-8 +# 用法: .\check_encoding.ps1 [文件路径或目录路径] +# 输出编码: UTF-8 + +param( + [Parameter(Mandatory=$false)] + [string]$Path = "." +) + +# 设置控制台和输出编码为 UTF-8,修复中文乱码 +if ([Console]::OutputEncoding.CodePage -ne 65001) { + chcp 65001 | Out-Null +} +[Console]::OutputEncoding = [System.Text.Encoding]::UTF8 +$PSDefaultParameterValues['*:Encoding'] = 'utf8' +$OutputEncoding = [System.Text.Encoding]::UTF8 + +# 定义代码文件扩展名列表 +$codeFileExtensions = @( + # 源代码文件 + '.cs', '.js', '.ts', '.jsx', '.tsx', '.java', '.py', '.cpp', '.c', '.h', '.hpp', + '.go', '.rs', '.rb', '.php', '.swift', '.kt', '.scala', '.vb', '.fs', '.dart', + # 配置文件/标记文件 + '.json', '.xml', '.html', '.htm', '.css', '.scss', '.sass', '.less', + '.yaml', '.yml', '.toml', '.ini', '.config', '.properties', '.conf', + # 脚本文件 + '.ps1', '.psm1', '.psd1', '.sh', '.bash', '.zsh', '.fish', '.bat', '.cmd', + # 数据/标记文件 + '.md', '.txt', '.log', '.csv', '.sql', '.r', '.m', '.mm', + # 其他文本格式 + '.vue', '.svelte', '.tsx', '.jsx', '.dts', '.map' +) + +function Test-IsCodeFile { + param([string]$FilePath) + + $extension = [System.IO.Path]::GetExtension($FilePath).ToLower() + return $codeFileExtensions -contains $extension +} + +function Test-IsUtf8 { + param([string]$FilePath) + + try { + # 读取文件的前几个字节检查 BOM + $bytes = [System.IO.File]::ReadAllBytes($FilePath) + + # 检查 UTF-8 BOM (EF BB BF) + if ($bytes.Length -ge 3 -and $bytes[0] -eq 0xEF -and $bytes[1] -eq 0xBB -and $bytes[2] -eq 0xBF) { + return @{ IsUtf8 = $true; HasBom = $true; Encoding = "UTF-8 with BOM" } + } + + # 尝试用 UTF-8 解码整个文件 + $content = [System.IO.File]::ReadAllText($FilePath, [System.Text.Encoding]::UTF8) + + # 检查是否包含无效的 UTF-8 序列(通过重新编码比较) + $utf8Bytes = [System.Text.Encoding]::UTF8.GetBytes($content) + $originalBytes = [System.IO.File]::ReadAllBytes($FilePath) + + # 如果重新编码后的字节与原始文件相同(忽略 BOM),则为有效 UTF-8 + if ($bytes.Length -ge 3 -and $bytes[0] -eq 0xEF -and $bytes[1] -eq 0xBB -and $bytes[2] -eq 0xBF) { + $originalBytes = $originalBytes[3..($originalBytes.Length-1)] + } + + # 简单检查:尝试用 UTF-8 解码,如果成功且能再编码回去,可能是 UTF-8 + # 更准确的方法是用 chardet 或类似库,但 PowerShell 内置方法如下: + try { + $decoded = [System.Text.Encoding]::UTF8.GetString($originalBytes) + $reencoded = [System.Text.Encoding]::UTF8.GetBytes($decoded) + + # 如果字节数组匹配(或接近),很可能是 UTF-8 + $match = $true + if ($reencoded.Length -ne $originalBytes.Length) { + $match = $false + } else { + for ($i = 0; $i -lt [Math]::Min($reencoded.Length, $originalBytes.Length); $i++) { + if ($reencoded[$i] -ne $originalBytes[$i]) { + $match = $false + break + } + } + } + + return @{ IsUtf8 = $match; HasBom = $false; Encoding = if ($match) { "UTF-8 without BOM" } else { "Unknown/Not UTF-8" } } + } catch { + return @{ IsUtf8 = $false; HasBom = $false; Encoding = "Not UTF-8" } + } + } catch { + return @{ IsUtf8 = $false; HasBom = $false; Encoding = "Error: $($_.Exception.Message)" } + } +} + +# 主逻辑 +if (Test-Path $Path -PathType Leaf) { + # 单个文件 + if (-not (Test-IsCodeFile -FilePath $Path)) { + Write-Host "Skipping non-code file: $Path" -ForegroundColor Gray + exit 0 + } + $result = Test-IsUtf8 -FilePath $Path + if (-not $result.IsUtf8) { + Write-Host "[X] Not UTF-8: $Path" -ForegroundColor Red + Write-Host " Encoding: $($result.Encoding)" -ForegroundColor Yellow + } +} elseif (Test-Path $Path -PathType Container) { + # 目录 + Write-Host "Checking directory: $Path" -ForegroundColor Cyan + Write-Host "" + + $allFiles = Get-ChildItem -Path $Path -File -Recurse + $files = $allFiles | Where-Object { Test-IsCodeFile -FilePath $_.FullName } + + if ($files.Count -eq 0) { + Write-Host "No code files found in the directory." -ForegroundColor Yellow + exit 0 + } + + Write-Host "Found $($files.Count) code file(s) (filtered from $($allFiles.Count) total files)" -ForegroundColor Gray + Write-Host "" + + $utf8Count = 0 + $nonUtf8Count = 0 + $nonUtf8Files = @() + + foreach ($file in $files) { + $result = Test-IsUtf8 -FilePath $file.FullName + if ($result.IsUtf8) { + $utf8Count++ + } else { + $nonUtf8Count++ + $nonUtf8Files += $file.FullName + Write-Host "[X] Not UTF-8: $($file.FullName)" -ForegroundColor Red + Write-Host " Encoding: $($result.Encoding)" -ForegroundColor Yellow + Write-Host "" + } + } + + Write-Host "Summary:" -ForegroundColor Cyan + Write-Host " Total code files: $($files.Count)" + Write-Host " UTF-8 files: $utf8Count" -ForegroundColor Green + if ($nonUtf8Count -gt 0) { + Write-Host " Non UTF-8 files: $nonUtf8Count" -ForegroundColor Red + } else { + Write-Host " Non UTF-8 files: 0" -ForegroundColor Green + Write-Host "" + Write-Host "All code files are UTF-8 encoded!" -ForegroundColor Green + } +} else { + Write-Host "Error: Path does not exist: $Path" -ForegroundColor Red + exit 1 +} + diff --git a/host/JiShe.IoT.HttpApi.Host/Program.cs b/host/JiShe.IoT.HttpApi.Host/Program.cs index 5bf06ff..43f69e0 100644 --- a/host/JiShe.IoT.HttpApi.Host/Program.cs +++ b/host/JiShe.IoT.HttpApi.Host/Program.cs @@ -1,4 +1,5 @@ using JiShe.ServicePro.Core; +using JiShe.ServicePro.Encrypt; namespace JiShe.IoT; @@ -13,27 +14,29 @@ public class Program //long nanosecondsFromSnowflakeId = ServicePro.Core.TimestampHelper.NextUnixNanosecondsFromSnowflakeId(); //long nanosecondsDateOffset = ServicePro.Core.TimestampHelper.ToUnixTimeNanoseconds(DateTimeOffset.UtcNow); - //BusinessSystemAggregation.Dto.BatchQueryDeviceDataInfoInput batchQueryDeviceDataInfoInput = new BusinessSystemAggregation.Dto.BatchQueryDeviceDataInfoInput() - //{ - // DeviceType = ServicePro.Enums.DeviceTypeEnum.Ammeter, - // DeviceAddresses = new List() - // { - // "332018305", - // "332053764", - // }, - // BeginTime = DateTime.Now.AddDays(-1), - // EndTime = DateTime.Now, - // IoTDataType = "Data", - //}; - //OpenApiRequest openApiRequest = new OpenApiRequest() - //{ - // Message = JiShe.ServicePro.Core.ServiceProJsonSerializer.Serialize(batchQueryDeviceDataInfoInput,false), - // Signature = "admin:admin123", - // Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), - // Nonce = "admin:admin123", - //}; + BusinessSystemAggregation.Dto.BatchQueryDeviceDataInfoInput batchQueryDeviceDataInfoInput = new BusinessSystemAggregation.Dto.BatchQueryDeviceDataInfoInput() + { + DeviceType = ServicePro.Enums.DeviceTypeEnum.SUB_DEVICE, + DeviceAddresses = new List() + { + "000000000001" + }, + BeginTime = new DateTime(2025,10,29), + EndTime = new DateTime(2025, 10, 31), + IoTDataType = "Data", + }; + OpenApiRequest openApiRequest = new OpenApiRequest() + { + Message = batchQueryDeviceDataInfoInput.Serialize(), + Signature = "admin:admin123", + Timestamp = 1762185062034, + Nonce = "44110100", + }; - //string signature = openApiRequest.Serialize(); + var signature = EncryptUtil.OpenApiSignature(openApiRequest.Message, openApiRequest.Timestamp, "SIcPQnpMgaFDmNlIjNmzq5smshz7cKrh", openApiRequest.Nonce); + openApiRequest.Signature = signature.Item2; + + string signatureSTR = openApiRequest.Serialize(); //string text = Convert.ToBase64String(Encoding.UTF8.GetBytes("admin:admin123")); @@ -51,7 +54,7 @@ public class Program .ConfigureAppConfiguration((context, builder) => { var env = context.HostingEnvironment.EnvironmentName; - Log.Information("ǰ " + env); + Log.Information("当前环境 :" + env); string[] filePathArray = new string[] { Environment.CurrentDirectory, "configs" }; string jsonPath = Path.Combine(filePathArray); @@ -62,11 +65,11 @@ public class Program await builder.AddApplicationAsync(); builder.WebHost.ConfigureKestrel((context, options) => { - options.Limits.MaxRequestBodySize = 100 * 1024 * 1024; // 100MB null + options.Limits.MaxRequestBodySize = 100 * 1024 * 1024; // 100MB null不受限制 options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2); options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(1); - //ȡĵСʣֽ/룩ΪNULLʾӦǿִСʡ////ȡĵСʣֽ/룩ΪNULLʾӦǿִСʡ + //获取或设置请求正文的最小数据速率(字节/秒)。将此属性设置为NULL表示不应强制执行最小数据速率。////获取或设置请求正文的最小数据速率(字节/秒)。将此属性设置为NULL表示不应强制执行最小数据速率。 options.Limits.MinRequestBodyDataRate = null;//new MinDataRate(bytesPerSecond: 2048, gracePeriod: TimeSpan.FromSeconds(10)); }); diff --git a/src/JiShe.IoT.Application/IoTAppService.cs b/src/JiShe.IoT.Application/IoTAppService.cs index 0527a85..2563e92 100644 --- a/src/JiShe.IoT.Application/IoTAppService.cs +++ b/src/JiShe.IoT.Application/IoTAppService.cs @@ -8,6 +8,7 @@ using JiShe.ServicePro.Enums; using JiShe.ServicePro.FreeRedisProvider; using JiShe.ServicePro.FreeSqlProvider; using JiShe.ServicePro.IoTDBManagement.TableModels; +using Microsoft.Extensions.Logging; using System.Xml.Linq; using Volo.Abp; @@ -97,6 +98,7 @@ namespace JiShe.IoT bool verifySignatureReult = EncryptUtil.OpenApiVerifySignature(input.Message, input.Nonce, input.Timestamp, input.Signature, serverOptions.SignatureToken); if (verifySignatureReult == false)//签名校验失败 { + LoggerFactory.CreateLogger("IoTAppService").LogError("签名校验失败"); return HttpDataResultExtensions.Failed(null, "签名校验失败", -1103); } diff --git a/src/JiShe.IoT.Application/IoTApplicationModule.cs b/src/JiShe.IoT.Application/IoTApplicationModule.cs index b25c2d3..3af5e33 100644 --- a/src/JiShe.IoT.Application/IoTApplicationModule.cs +++ b/src/JiShe.IoT.Application/IoTApplicationModule.cs @@ -1,4 +1,4 @@ -using JiShe.IoT.CommonServices; +using JiShe.IoT.CommonServices; using JiShe.IoT.Jobs.ToRedis; using JiShe.ServicePro.CTWingManagement; using JiShe.ServicePro.DeviceManagement; @@ -45,7 +45,7 @@ namespace JiShe.IoT public override void PostConfigureServices(ServiceConfigurationContext context) { - // ʱ + // 定时任务 //ConfigureBackgroundJob(context); } diff --git a/src/JiShe.IoT.Domain/Data/IoTDbMigrationService.cs b/src/JiShe.IoT.Domain/Data/IoTDbMigrationService.cs index f67266e..98f84da 100644 --- a/src/JiShe.IoT.Domain/Data/IoTDbMigrationService.cs +++ b/src/JiShe.IoT.Domain/Data/IoTDbMigrationService.cs @@ -1,4 +1,4 @@ -using JiShe.ServicePro.ApacheIoTDB.Provider.ISessionPools; +using JiShe.ServicePro.ApacheIoTDB.Provider.ISessionPools; using JiShe.ServicePro.ApacheIoTDB.Provider.SessionPools; namespace JiShe.IoT.Data @@ -89,12 +89,12 @@ namespace JiShe.IoT.Data } /// - /// ʼIoTDBģ + /// 初始化IoTDB表模型 /// /// private async Task InitIoTDBTable() { - //ʼIoTDBģ + //初始化IoTDB表模型 await _ioTDBSessionPoolProvider.InitTableSessionModelAsync(); }