修复部分代码文件非UTF8编码的问题

This commit is contained in:
ChenYi 2025-11-03 14:17:12 +08:00
parent b82a6d3329
commit 7d2b0422c8
5 changed files with 185 additions and 28 deletions

152
check_encoding.ps1 Normal file
View File

@ -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
}

View File

@ -1,4 +1,5 @@
using JiShe.ServicePro.Core; using JiShe.ServicePro.Core;
using JiShe.ServicePro.Encrypt;
namespace JiShe.IoT; namespace JiShe.IoT;
@ -13,27 +14,29 @@ public class Program
//long nanosecondsFromSnowflakeId = ServicePro.Core.TimestampHelper.NextUnixNanosecondsFromSnowflakeId(); //long nanosecondsFromSnowflakeId = ServicePro.Core.TimestampHelper.NextUnixNanosecondsFromSnowflakeId();
//long nanosecondsDateOffset = ServicePro.Core.TimestampHelper.ToUnixTimeNanoseconds(DateTimeOffset.UtcNow); //long nanosecondsDateOffset = ServicePro.Core.TimestampHelper.ToUnixTimeNanoseconds(DateTimeOffset.UtcNow);
//BusinessSystemAggregation.Dto.BatchQueryDeviceDataInfoInput batchQueryDeviceDataInfoInput = new BusinessSystemAggregation.Dto.BatchQueryDeviceDataInfoInput() BusinessSystemAggregation.Dto.BatchQueryDeviceDataInfoInput batchQueryDeviceDataInfoInput = new BusinessSystemAggregation.Dto.BatchQueryDeviceDataInfoInput()
//{ {
// DeviceType = ServicePro.Enums.DeviceTypeEnum.Ammeter, DeviceType = ServicePro.Enums.DeviceTypeEnum.SUB_DEVICE,
// DeviceAddresses = new List<string>() DeviceAddresses = new List<string>()
// { {
// "332018305", "000000000001"
// "332053764", },
// }, BeginTime = new DateTime(2025,10,29),
// BeginTime = DateTime.Now.AddDays(-1), EndTime = new DateTime(2025, 10, 31),
// EndTime = DateTime.Now, IoTDataType = "Data",
// IoTDataType = "Data", };
//}; OpenApiRequest openApiRequest = new OpenApiRequest()
//OpenApiRequest openApiRequest = new OpenApiRequest() {
//{ Message = batchQueryDeviceDataInfoInput.Serialize(),
// Message = JiShe.ServicePro.Core.ServiceProJsonSerializer.Serialize(batchQueryDeviceDataInfoInput,false), Signature = "admin:admin123",
// Signature = "admin:admin123", Timestamp = 1762185062034,
// Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), Nonce = "44110100",
// Nonce = "admin:admin123", };
//};
//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")); //string text = Convert.ToBase64String(Encoding.UTF8.GetBytes("admin:admin123"));
@ -51,7 +54,7 @@ public class Program
.ConfigureAppConfiguration((context, builder) => .ConfigureAppConfiguration((context, builder) =>
{ {
var env = context.HostingEnvironment.EnvironmentName; var env = context.HostingEnvironment.EnvironmentName;
Log.Information("当前环境 " + env); Log.Information("当前环境 " + env);
string[] filePathArray = new string[] { Environment.CurrentDirectory, "configs" }; string[] filePathArray = new string[] { Environment.CurrentDirectory, "configs" };
string jsonPath = Path.Combine(filePathArray); string jsonPath = Path.Combine(filePathArray);
@ -62,11 +65,11 @@ public class Program
await builder.AddApplicationAsync<JiShe.IoT.IoTHttpApiHostModule>(); await builder.AddApplicationAsync<JiShe.IoT.IoTHttpApiHostModule>();
builder.WebHost.ConfigureKestrel((context, options) => 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.KeepAliveTimeout = TimeSpan.FromMinutes(2);
options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(1); options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(1);
//获取或设置请求正文的最小数据速率(字节/秒。将此属性设置为NULL表示不应强制执行最小数据速率。////获取或设置请求正文的最小数据速率(字节/秒。将此属性设置为NULL表示不应强制执行最小数据速率。 //获取或设置请求正文的最小数据速率(字节/秒。将此属性设置为NULL表示不应强制执行最小数据速率。////获取或设置请求正文的最小数据速率(字节/秒。将此属性设置为NULL表示不应强制执行最小数据速率。
options.Limits.MinRequestBodyDataRate = null;//new MinDataRate(bytesPerSecond: 2048, gracePeriod: TimeSpan.FromSeconds(10)); options.Limits.MinRequestBodyDataRate = null;//new MinDataRate(bytesPerSecond: 2048, gracePeriod: TimeSpan.FromSeconds(10));
}); });

View File

@ -8,6 +8,7 @@ using JiShe.ServicePro.Enums;
using JiShe.ServicePro.FreeRedisProvider; using JiShe.ServicePro.FreeRedisProvider;
using JiShe.ServicePro.FreeSqlProvider; using JiShe.ServicePro.FreeSqlProvider;
using JiShe.ServicePro.IoTDBManagement.TableModels; using JiShe.ServicePro.IoTDBManagement.TableModels;
using Microsoft.Extensions.Logging;
using System.Xml.Linq; using System.Xml.Linq;
using Volo.Abp; using Volo.Abp;
@ -97,6 +98,7 @@ namespace JiShe.IoT
bool verifySignatureReult = EncryptUtil.OpenApiVerifySignature(input.Message, input.Nonce, input.Timestamp, input.Signature, serverOptions.SignatureToken); bool verifySignatureReult = EncryptUtil.OpenApiVerifySignature(input.Message, input.Nonce, input.Timestamp, input.Signature, serverOptions.SignatureToken);
if (verifySignatureReult == false)//签名校验失败 if (verifySignatureReult == false)//签名校验失败
{ {
LoggerFactory.CreateLogger("IoTAppService").LogError("签名校验失败");
return HttpDataResultExtensions.Failed<T>(null, "签名校验失败", -1103); return HttpDataResultExtensions.Failed<T>(null, "签名校验失败", -1103);
} }

View File

@ -1,4 +1,4 @@
using JiShe.IoT.CommonServices; using JiShe.IoT.CommonServices;
using JiShe.IoT.Jobs.ToRedis; using JiShe.IoT.Jobs.ToRedis;
using JiShe.ServicePro.CTWingManagement; using JiShe.ServicePro.CTWingManagement;
using JiShe.ServicePro.DeviceManagement; using JiShe.ServicePro.DeviceManagement;
@ -45,7 +45,7 @@ namespace JiShe.IoT
public override void PostConfigureServices(ServiceConfigurationContext context) public override void PostConfigureServices(ServiceConfigurationContext context)
{ {
// 定时任务 // 定时任务
//ConfigureBackgroundJob(context); //ConfigureBackgroundJob(context);
} }

View File

@ -1,4 +1,4 @@
using JiShe.ServicePro.ApacheIoTDB.Provider.ISessionPools; using JiShe.ServicePro.ApacheIoTDB.Provider.ISessionPools;
using JiShe.ServicePro.ApacheIoTDB.Provider.SessionPools; using JiShe.ServicePro.ApacheIoTDB.Provider.SessionPools;
namespace JiShe.IoT.Data namespace JiShe.IoT.Data
@ -89,12 +89,12 @@ namespace JiShe.IoT.Data
} }
/// <summary> /// <summary>
/// ³õʼ»¯IoTDB±íÄ£ÐÍ /// 初始化IoTDB表模型
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private async Task InitIoTDBTable() private async Task InitIoTDBTable()
{ {
//³õʼ»¯IoTDB±íÄ£ÐÍ //初始化IoTDB表模型
await _ioTDBSessionPoolProvider.InitTableSessionModelAsync(); await _ioTDBSessionPoolProvider.InitTableSessionModelAsync();
} }