feat: 实现 FOD 日志数据采集 CLI 应用

This commit is contained in:
ssss
2026-07-02 18:13:56 +08:00
parent c4e5ac0360
commit 3dcd9f7c0b
52 changed files with 3144 additions and 354 deletions

View File

@@ -0,0 +1,123 @@
# 文件名解析器
> 所属模块:[解析器设计](./概览.md)
---
## 1. 文件名格式
**格式约定**`TX面板-TX硬件-TX软件-RX类型-测试目的-年月日-测试次数.log`
**分隔符**:支持 `-`(短横线)和 `_`(下划线)两种分隔符,文件名解析时将同时拆分这两种字符。
> ⚠️ **注意**:字段值内部不应包含分隔符字符。例如,若 TX面板值为 `single-mold`,解析时会拆分为 `single` 和 `mold` 两个字段,导致解析失败。请确保字段值本身不含 `-` 或 `_`。
**示例**
- 标准:`singleMold-v1.0-hex2_1-iPhone15-compatibility-20260702-1.log`(字段值无分隔符)
- 避免:`single-mold-v1.0-hex2.1-iPhone15-兼容性测试-20260702-1.log``single-mold` 会拆分)
**位置说明**:表格中的"位置"采用 1-based 索引(从 1 开始计数),与代码中的 0-based 数组索引对应。
---
## 2. 字段映射
| 位置 | 字段 | 对应维度表 | 示例值 |
|------|------|------------|--------|
| 1 | TxPanel | tx_panel.name | single-mold |
| 2 | TxHardware | tx_hardware.version | v1.0 |
| 3 | TxSoftware | tx_software.version | hex2.1 |
| 4 | RxType | rx_type.name | iPhone15 |
| 5 | TestPurpose | test_scenario.test_purpose | 兼容性测试 |
| 6 | TestDate | test_scenario.test_date | 20260702 |
| 7 | TestSequence | test_scenario.test_sequence | 1 |
---
## 3. 解析器实现
```csharp
// Parsers/FileNameParser.cs
using System.Globalization;
using WCTDataMiner.Services;
namespace WCTDataMiner.Parsers;
public class FileNameParser
{
private static readonly char[] Separators = { '-', '_' };
/// <summary>
/// 解析日志文件名,提取场景信息
/// </summary>
/// <param name="fileName">文件名(不含路径)</param>
/// <returns>场景信息,若格式不匹配返回 null</returns>
public ScenarioInfo? Parse(string fileName)
{
// 移除 .log 扩展名
var nameWithoutExt = Path.GetFileNameWithoutExtension(fileName);
if (string.IsNullOrEmpty(nameWithoutExt))
return null;
var parts = nameWithoutExt.Split(Separators);
if (parts.Length < 7)
return null;
// 解析日期
if (!TryParseDate(parts[5], out var testDate))
return null;
// 解析测试序号
if (!int.TryParse(parts[6], out var testSequence))
testSequence = 1;
return new ScenarioInfo(
TxPanel: parts[0],
TxHardware: parts[1],
TxSoftware: parts[2],
RxType: parts[3],
TestPurpose: parts.Length > 4 ? parts[4] : null,
TestDate: testDate,
TestSequence: testSequence
);
}
private static bool TryParseDate(string dateStr, out DateOnly date)
{
// 支持多种日期格式
var formats = new[] { "yyyyMMdd", "yyyy-MM-dd", "yyMMdd" };
return DateOnly.TryParseExact(dateStr, formats, CultureInfo.InvariantCulture, DateTimeStyles.None, out date);
}
}
```
---
## 4. 容错处理
| 场景 | 处理方式 |
|------|----------|
| 文件名为空或 null | 返回 nullParseService 记录错误日志 |
| 文件名仅含扩展名(如 `.log` | 返回 null |
| 文件名少于 7 个字段 | 返回 null缺少必要字段 |
| 日期格式不匹配 | 返回 null无法解析 test_date |
| 测试序号解析失败 | 使用默认值 1 |
| 文件名扩展名无效(非 `.log` | 仍会解析,仅去除扩展名后尝试 |
> **说明**:由于解析器要求 `parts.Length >= 7` 才会成功返回,"测试目的缺失"不会单独发生——当字段不足时整体解析失败。若需支持可选字段,需调整解析逻辑。
---
## 5. 使用示例
```csharp
// 在 ParseService 中使用
var fileNameParser = new FileNameParser();
var scenarioInfo = fileNameParser.Parse("single-mold-v1.0-hex2.1-iPhone15-兼容性测试-20260702-1.log");
if (scenarioInfo != null)
{
var scenario = await scenarioService.GetOrCreateScenarioAsync(scenarioInfo);
// 继续解析文件内容...
}
```