refactor(project): 迁移项目命名并移除WPF客户端
This commit is contained in:
@@ -3,11 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.0.31903.59
|
VisualStudioVersion = 17.0.31903.59
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WCTDataMiner.Core", "src\WCTDataMiner.Core\WCTDataMiner.Core.csproj", "{A1B2C3D4-1234-5678-9ABC-DEF012345601}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gpulse.WCT.DataAnalyzer.Core", "src\Gpulse.WCT.DataAnalyzer.Core\Gpulse.WCT.DataAnalyzer.Core.csproj", "{A1B2C3D4-1234-5678-9ABC-DEF012345601}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WCTDataMiner.Wpf", "src\WCTDataMiner.Wpf\WCTDataMiner.Wpf.csproj", "{A1B2C3D4-1234-5678-9ABC-DEF012345602}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gpulse.WCT.DataAnalyzer", "src\Gpulse.WCT.DataAnalyzer\Gpulse.WCT.DataAnalyzer.csproj", "{A1B2C3D4-1234-5678-9ABC-DEF012345603}"
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WCTDataMiner", "src\WCTDataMiner\WCTDataMiner.csproj", "{A1B2C3D4-1234-5678-9ABC-DEF012345603}"
|
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@@ -19,10 +17,6 @@ Global
|
|||||||
{A1B2C3D4-1234-5678-9ABC-DEF012345601}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{A1B2C3D4-1234-5678-9ABC-DEF012345601}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{A1B2C3D4-1234-5678-9ABC-DEF012345601}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{A1B2C3D4-1234-5678-9ABC-DEF012345601}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{A1B2C3D4-1234-5678-9ABC-DEF012345601}.Release|Any CPU.Build.0 = Release|Any CPU
|
{A1B2C3D4-1234-5678-9ABC-DEF012345601}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{A1B2C3D4-1234-5678-9ABC-DEF012345602}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{A1B2C3D4-1234-5678-9ABC-DEF012345602}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{A1B2C3D4-1234-5678-9ABC-DEF012345602}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{A1B2C3D4-1234-5678-9ABC-DEF012345602}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{A1B2C3D4-1234-5678-9ABC-DEF012345603}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{A1B2C3D4-1234-5678-9ABC-DEF012345603}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{A1B2C3D4-1234-5678-9ABC-DEF012345603}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{A1B2C3D4-1234-5678-9ABC-DEF012345603}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{A1B2C3D4-1234-5678-9ABC-DEF012345603}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{A1B2C3D4-1234-5678-9ABC-DEF012345603}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WCTDataMiner.Core.Configuration;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Configuration;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 应用配置
|
/// 应用配置
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
using WCTDataMiner.Core.Models;
|
using Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Data.Configurations;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Data.Configurations;
|
||||||
|
|
||||||
public class PlossRecordConfiguration : IEntityTypeConfiguration<PlossRecord>
|
public class PlossRecordConfiguration : IEntityTypeConfiguration<PlossRecord>
|
||||||
{
|
{
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
using WCTDataMiner.Core.Models;
|
using Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Data.Configurations;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Data.Configurations;
|
||||||
|
|
||||||
public class QfodRecordConfiguration : IEntityTypeConfiguration<QfodRecord>
|
public class QfodRecordConfiguration : IEntityTypeConfiguration<QfodRecord>
|
||||||
{
|
{
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
using WCTDataMiner.Core.Models;
|
using Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Data.Configurations;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Data.Configurations;
|
||||||
|
|
||||||
public class RxTypeConfiguration : IEntityTypeConfiguration<RxType>
|
public class RxTypeConfiguration : IEntityTypeConfiguration<RxType>
|
||||||
{
|
{
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
using WCTDataMiner.Core.Models;
|
using Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Data.Configurations;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Data.Configurations;
|
||||||
|
|
||||||
public class TestScenarioConfiguration : IEntityTypeConfiguration<TestScenario>
|
public class TestScenarioConfiguration : IEntityTypeConfiguration<TestScenario>
|
||||||
{
|
{
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
using WCTDataMiner.Core.Models;
|
using Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Data.Configurations;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Data.Configurations;
|
||||||
|
|
||||||
public class TxHardwareConfiguration : IEntityTypeConfiguration<TxHardware>
|
public class TxHardwareConfiguration : IEntityTypeConfiguration<TxHardware>
|
||||||
{
|
{
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
using WCTDataMiner.Core.Models;
|
using Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Data.Configurations;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Data.Configurations;
|
||||||
|
|
||||||
public class TxPanelConfiguration : IEntityTypeConfiguration<TxPanel>
|
public class TxPanelConfiguration : IEntityTypeConfiguration<TxPanel>
|
||||||
{
|
{
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
using WCTDataMiner.Core.Models;
|
using Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Data.Configurations;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Data.Configurations;
|
||||||
|
|
||||||
public class TxSoftwareConfiguration : IEntityTypeConfiguration<TxSoftware>
|
public class TxSoftwareConfiguration : IEntityTypeConfiguration<TxSoftware>
|
||||||
{
|
{
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Data;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Data;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 数据库上下文工厂实现 - 支持SQLite和PostgreSQL切换
|
/// 数据库上下文工厂实现 - 支持SQLite和PostgreSQL切换
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WCTDataMiner.Core.Data;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Data;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 数据库上下文工厂接口
|
/// 数据库上下文工厂接口
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using WCTDataMiner.Core.Models;
|
using Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Data;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Data;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 初始数据种子
|
/// 初始数据种子
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using WCTDataMiner.Core.Models;
|
using Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Data;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Data;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// WCT数据采集数据库上下文
|
/// WCT数据采集数据库上下文
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using WCTDataMiner.Core.Data;
|
using Gpulse.WCT.DataAnalyzer.Core.Data;
|
||||||
using WCTDataMiner.Core.Parsers;
|
using Gpulse.WCT.DataAnalyzer.Core.Parsers;
|
||||||
using WCTDataMiner.Core.Services;
|
using Gpulse.WCT.DataAnalyzer.Core.Services;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Extensions;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Extensions;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 服务注册扩展
|
/// 服务注册扩展
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
<AssemblyName>Gpulse.WCT.DataAnalyzer.Core</AssemblyName>
|
||||||
|
<RootNamespace>Gpulse.WCT.DataAnalyzer.Core</RootNamespace>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WCTDataMiner.Core.Models;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ploss记录实体 - 存储Ploss FOD格式解析数据
|
/// Ploss记录实体 - 存储Ploss FOD格式解析数据
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WCTDataMiner.Core.Models;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Qfod记录实体 - 存储Qfod格式解析数据
|
/// Qfod记录实体 - 存储Qfod格式解析数据
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WCTDataMiner.Core.Models;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// RX类型维度表
|
/// RX类型维度表
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WCTDataMiner.Core.Models;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 测试场景实体 - 通过外键关联各维度表
|
/// 测试场景实体 - 通过外键关联各维度表
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WCTDataMiner.Core.Models;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// TX硬件版本维度表
|
/// TX硬件版本维度表
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WCTDataMiner.Core.Models;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// TX面板类型维度表
|
/// TX面板类型维度表
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WCTDataMiner.Core.Models;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// TX软件版本维度表
|
/// TX软件版本维度表
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Parsers;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Parsers;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 文件名解析器 - 从文件名提取场景信息
|
/// 文件名解析器 - 从文件名提取场景信息
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WCTDataMiner.Core.Parsers;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Parsers;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 通用解析器接口
|
/// 通用解析器接口
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using WCTDataMiner.Core.Models;
|
using Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Parsers;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Parsers;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ploss FOD日志解析器 - 支持两行格式
|
/// Ploss FOD日志解析器 - 支持两行格式
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using WCTDataMiner.Core.Models;
|
using Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Parsers;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Parsers;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Qfod日志解析器
|
/// Qfod日志解析器
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Security;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Security;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 路径验证结果
|
/// 路径验证结果
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WCTDataMiner.Core.Security;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Security;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 安全相关常量定义
|
/// 安全相关常量定义
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using WCTDataMiner.Core.Data;
|
using Gpulse.WCT.DataAnalyzer.Core.Data;
|
||||||
using WCTDataMiner.Core.Models;
|
using Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Services;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Services;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 数据清理服务 - 支持软删除
|
/// 数据清理服务 - 支持软删除
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using WCTDataMiner.Core.Data;
|
using Gpulse.WCT.DataAnalyzer.Core.Data;
|
||||||
using WCTDataMiner.Core.Models;
|
using Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Services;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Services;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 维度表管理服务 - 负责维度表的CRUD操作(并发安全版本)
|
/// 维度表管理服务 - 负责维度表的CRUD操作(并发安全版本)
|
||||||
@@ -3,11 +3,11 @@ using System.Text;
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using WCTDataMiner.Core.Data;
|
using Gpulse.WCT.DataAnalyzer.Core.Data;
|
||||||
using WCTDataMiner.Core.Models;
|
using Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
using WCTDataMiner.Core.Security;
|
using Gpulse.WCT.DataAnalyzer.Core.Security;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Services;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Services;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 数据导出服务 - 支持安全的路径验证和 RFC 4180 标准 CSV 转义
|
/// 数据导出服务 - 支持安全的路径验证和 RFC 4180 标准 CSV 转义
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using WCTDataMiner.Core.Data;
|
using Gpulse.WCT.DataAnalyzer.Core.Data;
|
||||||
using WCTDataMiner.Core.Models;
|
using Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
using WCTDataMiner.Core.Parsers;
|
using Gpulse.WCT.DataAnalyzer.Core.Parsers;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Services;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Services;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 解析流程协调服务 - 协调文件名解析、行解析、批量写入
|
/// 解析流程协调服务 - 协调文件名解析、行解析、批量写入
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using WCTDataMiner.Core.Data;
|
using Gpulse.WCT.DataAnalyzer.Core.Data;
|
||||||
using WCTDataMiner.Core.Models;
|
using Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
using WCTDataMiner.Core.Parsers;
|
using Gpulse.WCT.DataAnalyzer.Core.Parsers;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Services;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Services;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 篮选条件常量
|
/// 篮选条件常量
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using WCTDataMiner.Core.Data;
|
using Gpulse.WCT.DataAnalyzer.Core.Data;
|
||||||
using WCTDataMiner.Core.Models;
|
using Gpulse.WCT.DataAnalyzer.Core.Models;
|
||||||
|
|
||||||
namespace WCTDataMiner.Core.Services;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Services;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 统计查询服务 - 使用数据库端聚合优化内存效率
|
/// 统计查询服务 - 使用数据库端聚合优化内存效率
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace WCTDataMiner.Core.Services;
|
namespace Gpulse.WCT.DataAnalyzer.Core.Services;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 阈值计算器 - 根据接收功率查表获取动态阈值
|
/// 阈值计算器 - 根据接收功率查表获取动态阈值
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using System.CommandLine;
|
using System.CommandLine;
|
||||||
using WCTDataMiner.Core.Services;
|
using Gpulse.WCT.DataAnalyzer.Core.Services;
|
||||||
|
|
||||||
namespace WCTDataMiner.Commands;
|
namespace Gpulse.WCT.DataAnalyzer.Commands;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 数据清理命令
|
/// 数据清理命令
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using System.CommandLine;
|
using System.CommandLine;
|
||||||
using WCTDataMiner.Core.Services;
|
using Gpulse.WCT.DataAnalyzer.Core.Services;
|
||||||
|
|
||||||
namespace WCTDataMiner.Commands;
|
namespace Gpulse.WCT.DataAnalyzer.Commands;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 数据导出命令
|
/// 数据导出命令
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using System.CommandLine;
|
using System.CommandLine;
|
||||||
using WCTDataMiner.Core.Services;
|
using Gpulse.WCT.DataAnalyzer.Core.Services;
|
||||||
|
|
||||||
namespace WCTDataMiner.Commands;
|
namespace Gpulse.WCT.DataAnalyzer.Commands;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 解析日志文件命令
|
/// 解析日志文件命令
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using System.CommandLine;
|
using System.CommandLine;
|
||||||
using WCTDataMiner.Core.Services;
|
using Gpulse.WCT.DataAnalyzer.Core.Services;
|
||||||
|
|
||||||
namespace WCTDataMiner.Commands;
|
namespace Gpulse.WCT.DataAnalyzer.Commands;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 统计查询命令
|
/// 统计查询命令
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
<AssemblyName>Gpulse.WCT.DataAnalyzer</AssemblyName>
|
||||||
|
<RootNamespace>Gpulse.WCT.DataAnalyzer</RootNamespace>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
@@ -30,7 +32,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\WCTDataMiner.Core\WCTDataMiner.Core.csproj" />
|
<ProjectReference Include="..\Gpulse.WCT.DataAnalyzer.Core\Gpulse.WCT.DataAnalyzer.Core.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -3,15 +3,15 @@ using Microsoft.Extensions.Configuration;
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using WCTDataMiner.Commands;
|
using Gpulse.WCT.DataAnalyzer.Commands;
|
||||||
using WCTDataMiner.Core.Data;
|
using Gpulse.WCT.DataAnalyzer.Core.Data;
|
||||||
using WCTDataMiner.Core.Extensions;
|
using Gpulse.WCT.DataAnalyzer.Core.Extensions;
|
||||||
using WCTDataMiner.Core.Services;
|
using Gpulse.WCT.DataAnalyzer.Core.Services;
|
||||||
|
|
||||||
namespace WCTDataMiner;
|
namespace Gpulse.WCT.DataAnalyzer;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// WCTDataMiner - 无线充电FOD日志数据采集系统
|
/// Gpulse.WCT.DataAnalyzer - 无线充电FOD日志数据采集系统
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
@@ -67,7 +67,7 @@ public class Program
|
|||||||
using var commandScope = app.Services.CreateScope();
|
using var commandScope = app.Services.CreateScope();
|
||||||
var provider = commandScope.ServiceProvider;
|
var provider = commandScope.ServiceProvider;
|
||||||
|
|
||||||
var rootCommand = new RootCommand("WCTDataMiner - FOD Log Data Parser");
|
var rootCommand = new RootCommand("Gpulse.WCT.DataAnalyzer - FOD Log Data Parser");
|
||||||
|
|
||||||
rootCommand.AddCommand(new ParseCommand(provider.GetRequiredService<ParseService>()));
|
rootCommand.AddCommand(new ParseCommand(provider.GetRequiredService<ParseService>()));
|
||||||
rootCommand.AddCommand(new StatsCommand(provider.GetRequiredService<StatsService>()));
|
rootCommand.AddCommand(new StatsCommand(provider.GetRequiredService<StatsService>()));
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<Application x:Class="WCTDataMiner.Wpf.App"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:local="clr-namespace:WCTDataMiner.Wpf"
|
|
||||||
xmlns:converters="clr-namespace:WCTDataMiner.Wpf.Converters">
|
|
||||||
<Application.Resources>
|
|
||||||
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
|
||||||
<converters:InverseBooleanConverter x:Key="InverseBooleanConverter"/>
|
|
||||||
</Application.Resources>
|
|
||||||
</Application>
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
using System.IO;
|
|
||||||
using System.Windows;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
using Serilog;
|
|
||||||
using WCTDataMiner.Core.Extensions;
|
|
||||||
using WCTDataMiner.Core.Services;
|
|
||||||
using WCTDataMiner.Wpf.Configuration;
|
|
||||||
using WCTDataMiner.Wpf.ViewModels;
|
|
||||||
using WCTDataMiner.Wpf.Views;
|
|
||||||
|
|
||||||
namespace WCTDataMiner.Wpf;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Interaction logic for App.xaml
|
|
||||||
/// </summary>
|
|
||||||
public partial class App : Application
|
|
||||||
{
|
|
||||||
private IHost? _host;
|
|
||||||
private ILogger? _logger;
|
|
||||||
|
|
||||||
protected override void OnStartup(StartupEventArgs e)
|
|
||||||
{
|
|
||||||
// 使用 ConfigurationLoader 加载配置,支持文件缺失
|
|
||||||
var configuration = ConfigurationLoader.LoadConfiguration(
|
|
||||||
AppDomain.CurrentDomain.BaseDirectory,
|
|
||||||
out var configFileExists);
|
|
||||||
|
|
||||||
// 配置 Serilog - 从配置文件读取
|
|
||||||
Log.Logger = new LoggerConfiguration()
|
|
||||||
.ReadFrom.Configuration(configuration)
|
|
||||||
.Enrich.FromLogContext()
|
|
||||||
.CreateLogger();
|
|
||||||
|
|
||||||
_logger = Log.ForContext<App>();
|
|
||||||
|
|
||||||
if (!configFileExists)
|
|
||||||
{
|
|
||||||
_logger.Information("配置文件 appsettings.json 不存在,使用默认配置启动");
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.Information("WCTDataMiner WPF 应用启动");
|
|
||||||
|
|
||||||
_host = Host.CreateDefaultBuilder()
|
|
||||||
.ConfigureAppConfiguration((context, configBuilder) =>
|
|
||||||
{
|
|
||||||
configBuilder.Sources.Clear();
|
|
||||||
configBuilder.SetBasePath(AppDomain.CurrentDomain.BaseDirectory);
|
|
||||||
|
|
||||||
if (configFileExists)
|
|
||||||
{
|
|
||||||
configBuilder.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
configBuilder.AddInMemoryCollection(DefaultAppSettings.GetDefaultConfiguration());
|
|
||||||
}
|
|
||||||
|
|
||||||
configBuilder.AddEnvironmentVariables("WCTDM_");
|
|
||||||
})
|
|
||||||
.ConfigureServices((context, services) =>
|
|
||||||
{
|
|
||||||
// 添加 Serilog
|
|
||||||
services.AddSerilog();
|
|
||||||
|
|
||||||
// 注册 Core 层服务
|
|
||||||
services.AddDatabaseServices(context.Configuration);
|
|
||||||
services.AddApplicationServices();
|
|
||||||
|
|
||||||
// 注册 ViewModels(使用 Singleton 确保消息订阅正确工作)
|
|
||||||
services.AddSingleton<MainViewModel>();
|
|
||||||
services.AddSingleton<ScenarioListViewModel>();
|
|
||||||
// Chart ViewModels 使用 Transient,每次导航创建新实例
|
|
||||||
services.AddTransient<PlossChartViewModel>();
|
|
||||||
services.AddTransient<QfodChartViewModel>();
|
|
||||||
// Table ViewModels 使用 Transient,每次导航创建新实例
|
|
||||||
services.AddTransient<PlossTableViewModel>();
|
|
||||||
services.AddTransient<QfodTableViewModel>();
|
|
||||||
services.AddSingleton<ImportViewModel>();
|
|
||||||
|
|
||||||
// 注册 Views
|
|
||||||
services.AddTransient<MainWindow>();
|
|
||||||
services.AddTransient<ScenarioListView>();
|
|
||||||
services.AddTransient<PlossChartView>();
|
|
||||||
services.AddTransient<QfodChartView>();
|
|
||||||
services.AddTransient<PlossTableView>();
|
|
||||||
services.AddTransient<QfodTableView>();
|
|
||||||
services.AddTransient<ImportView>();
|
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var mainWindow = _host.Services.GetRequiredService<MainWindow>();
|
|
||||||
|
|
||||||
// 初始化加载场景数据
|
|
||||||
var mainViewModel = _host.Services.GetRequiredService<MainViewModel>();
|
|
||||||
mainWindow.Loaded += async (s, e) =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await mainViewModel.InitializeAsync();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger?.Error(ex, "主窗口初始化失败");
|
|
||||||
MessageBox.Show($"应用初始化失败: {ex.Message}", "错误",
|
|
||||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
mainWindow.Show();
|
|
||||||
|
|
||||||
base.OnStartup(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnExit(ExitEventArgs e)
|
|
||||||
{
|
|
||||||
_logger?.Information("WCTDataMiner WPF 应用退出");
|
|
||||||
Log.CloseAndFlush();
|
|
||||||
_host?.Dispose();
|
|
||||||
base.OnExit(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
using System.Windows;
|
|
||||||
|
|
||||||
[assembly:ThemeInfo(
|
|
||||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
|
||||||
//(used if a resource is not found in the page,
|
|
||||||
// or application resource dictionaries)
|
|
||||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
|
||||||
//(used if a resource is not found in the page,
|
|
||||||
// app, or any theme specific resource dictionaries)
|
|
||||||
)]
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
using System.IO;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
|
|
||||||
namespace WCTDataMiner.Wpf.Configuration;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 配置加载器 - 支持配置文件缺失时的默认配置
|
|
||||||
/// </summary>
|
|
||||||
public static class ConfigurationLoader
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 加载配置,如果文件不存在则使用默认配置
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="basePath">配置文件基础路径</param>
|
|
||||||
/// <param name="configFileExists">输出参数:指示配置文件是否存在</param>
|
|
||||||
/// <returns>配置对象</returns>
|
|
||||||
public static IConfiguration LoadConfiguration(string basePath, out bool configFileExists)
|
|
||||||
{
|
|
||||||
var settingsPath = Path.Combine(basePath, "appsettings.json");
|
|
||||||
configFileExists = File.Exists(settingsPath);
|
|
||||||
|
|
||||||
var builder = new ConfigurationBuilder().SetBasePath(basePath);
|
|
||||||
|
|
||||||
if (configFileExists)
|
|
||||||
{
|
|
||||||
builder.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 使用默认配置
|
|
||||||
builder.AddInMemoryCollection(DefaultAppSettings.GetDefaultConfiguration());
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.AddEnvironmentVariables("WCTDM_");
|
|
||||||
return builder.Build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
namespace WCTDataMiner.Wpf.Configuration;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 默认应用配置 - 当配置文件缺失时使用
|
|
||||||
/// </summary>
|
|
||||||
public static class DefaultAppSettings
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 获取默认配置字典
|
|
||||||
/// </summary>
|
|
||||||
public static Dictionary<string, string?> GetDefaultConfiguration()
|
|
||||||
{
|
|
||||||
return new Dictionary<string, string?>
|
|
||||||
{
|
|
||||||
// Serilog 配置
|
|
||||||
["Serilog:MinimumLevel:Default"] = "Information",
|
|
||||||
["Serilog:MinimumLevel:Override:WCTDataMiner"] = "Debug",
|
|
||||||
["Serilog:MinimumLevel:Override:Microsoft"] = "Warning",
|
|
||||||
["Serilog:WriteTo:0:Name"] = "Console",
|
|
||||||
["Serilog:WriteTo:1:Name"] = "File",
|
|
||||||
["Serilog:WriteTo:1:Args:path"] = "./data/logs/wctdataminer-.log",
|
|
||||||
["Serilog:WriteTo:1:Args:rollingInterval"] = "Day",
|
|
||||||
["Serilog:WriteTo:1:Args:outputTemplate"] = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}",
|
|
||||||
|
|
||||||
// 数据库配置
|
|
||||||
["Database:Type"] = "sqlite",
|
|
||||||
["Database:Path"] = "./data/database/wctminer.db"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
using System.Globalization;
|
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Data;
|
|
||||||
|
|
||||||
namespace WCTDataMiner.Wpf.Converters;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Boolean to Visibility 转换器
|
|
||||||
/// </summary>
|
|
||||||
public class BooleanToVisibilityConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
|
||||||
{
|
|
||||||
if (value is bool boolValue)
|
|
||||||
{
|
|
||||||
return boolValue ? Visibility.Visible : Visibility.Collapsed;
|
|
||||||
}
|
|
||||||
return Visibility.Collapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
|
||||||
{
|
|
||||||
if (value is Visibility visibility)
|
|
||||||
{
|
|
||||||
return visibility == Visibility.Visible;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 反转 Boolean 转换器
|
|
||||||
/// </summary>
|
|
||||||
public class InverseBooleanConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
|
||||||
{
|
|
||||||
if (value is bool boolValue)
|
|
||||||
{
|
|
||||||
return !boolValue;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
|
||||||
{
|
|
||||||
if (value is bool boolValue)
|
|
||||||
{
|
|
||||||
return !boolValue;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
<Window x:Class="WCTDataMiner.Wpf.MainWindow"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:views="clr-namespace:WCTDataMiner.Wpf.Views"
|
|
||||||
xmlns:viewmodels="clr-namespace:WCTDataMiner.Wpf.ViewModels"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
Title="WCTDataMiner - FOD 数据分析工具" Height="600" Width="900"
|
|
||||||
WindowStartupLocation="CenterScreen">
|
|
||||||
|
|
||||||
<Grid>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="200"/>
|
|
||||||
<ColumnDefinition Width="*"/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
|
|
||||||
<!-- 左侧导航栏 -->
|
|
||||||
<Border Grid.Column="0" Background="#F5F5F5" BorderBrush="#DDD" BorderThickness="0,0,1,0">
|
|
||||||
<StackPanel Margin="10">
|
|
||||||
<TextBlock Text="导航" FontSize="16" FontWeight="Bold" Margin="0,0,0,15"/>
|
|
||||||
|
|
||||||
<Button Content="数据导入" Command="{Binding NavigateToImportCommand}"
|
|
||||||
Margin="0,5" Padding="10,5" HorizontalAlignment="Stretch"
|
|
||||||
Background="#4CAF50" Foreground="White" FontWeight="Bold"/>
|
|
||||||
|
|
||||||
<Button Content="场景列表" Command="{Binding NavigateToScenariosCommand}"
|
|
||||||
Margin="0,5" Padding="10,5" HorizontalAlignment="Stretch"/>
|
|
||||||
|
|
||||||
<TextBlock Text="筛选条件" FontSize="14" FontWeight="Bold" Margin="0,20,0,10"/>
|
|
||||||
|
|
||||||
<TextBlock Text="TX 面板:" Margin="0,5"/>
|
|
||||||
<ComboBox ItemsSource="{Binding TxPanels}" SelectedItem="{Binding SelectedTxPanel}"
|
|
||||||
Margin="0,0,0,10"/>
|
|
||||||
|
|
||||||
<TextBlock Text="TX 硬件:" Margin="0,5"/>
|
|
||||||
<ComboBox ItemsSource="{Binding TxHardwares}" SelectedItem="{Binding SelectedTxHardware}"
|
|
||||||
Margin="0,0,0,10"/>
|
|
||||||
|
|
||||||
<TextBlock Text="TX 软件:" Margin="0,5"/>
|
|
||||||
<ComboBox ItemsSource="{Binding TxSoftwares}" SelectedItem="{Binding SelectedTxSoftware}"
|
|
||||||
Margin="0,0,0,10"/>
|
|
||||||
|
|
||||||
<TextBlock Text="RX 类型:" Margin="0,5"/>
|
|
||||||
<ComboBox ItemsSource="{Binding RxTypes}" SelectedItem="{Binding SelectedRxType}"
|
|
||||||
Margin="0,0,0,10"/>
|
|
||||||
</StackPanel>
|
|
||||||
</Border>
|
|
||||||
|
|
||||||
<!-- 右侧内容区域 -->
|
|
||||||
<ContentControl Grid.Column="1" Content="{Binding CurrentView}">
|
|
||||||
<ContentControl.Resources>
|
|
||||||
<DataTemplate DataType="{x:Type viewmodels:ImportViewModel}">
|
|
||||||
<views:ImportView/>
|
|
||||||
</DataTemplate>
|
|
||||||
<DataTemplate DataType="{x:Type viewmodels:ScenarioListViewModel}">
|
|
||||||
<views:ScenarioListView/>
|
|
||||||
</DataTemplate>
|
|
||||||
<DataTemplate DataType="{x:Type viewmodels:PlossChartViewModel}">
|
|
||||||
<views:PlossChartView/>
|
|
||||||
</DataTemplate>
|
|
||||||
<DataTemplate DataType="{x:Type viewmodels:QfodChartViewModel}">
|
|
||||||
<views:QfodChartView/>
|
|
||||||
</DataTemplate>
|
|
||||||
<DataTemplate DataType="{x:Type viewmodels:PlossTableViewModel}">
|
|
||||||
<views:PlossTableView/>
|
|
||||||
</DataTemplate>
|
|
||||||
<DataTemplate DataType="{x:Type viewmodels:QfodTableViewModel}">
|
|
||||||
<views:QfodTableView/>
|
|
||||||
</DataTemplate>
|
|
||||||
</ContentControl.Resources>
|
|
||||||
</ContentControl>
|
|
||||||
</Grid>
|
|
||||||
</Window>
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
using System.Windows;
|
|
||||||
using WCTDataMiner.Wpf.ViewModels;
|
|
||||||
|
|
||||||
namespace WCTDataMiner.Wpf;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Interaction logic for MainWindow.xaml
|
|
||||||
/// </summary>
|
|
||||||
public partial class MainWindow : Window
|
|
||||||
{
|
|
||||||
public MainWindow(MainViewModel viewModel)
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
DataContext = viewModel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
namespace WCTDataMiner.Wpf.Messages;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 数据导入完成消息
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="ImportedCount">导入的文件数量</param>
|
|
||||||
public record DataImportedMessage(int ImportedCount);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 导航到 Ploss 图表消息
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="ScenarioId">场景 ID</param>
|
|
||||||
public record NavigateToPlossChartMessage(Guid ScenarioId);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 导航到 Qfod 图表消息
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="ScenarioId">场景 ID</param>
|
|
||||||
public record NavigateToQfodChartMessage(Guid ScenarioId);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 导航到 Ploss 表格消息
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="ScenarioId">场景 ID</param>
|
|
||||||
public record NavigateToPlossTableMessage(Guid ScenarioId);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 导航到 Qfod 表格消息
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="ScenarioId">场景 ID</param>
|
|
||||||
public record NavigateToQfodTableMessage(Guid ScenarioId);
|
|
||||||
@@ -1,170 +0,0 @@
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
|
||||||
using CommunityToolkit.Mvvm.Input;
|
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Win32;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using WCTDataMiner.Core.Services;
|
|
||||||
using WCTDataMiner.Wpf.Messages;
|
|
||||||
|
|
||||||
namespace WCTDataMiner.Wpf.ViewModels;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 数据导入 ViewModel
|
|
||||||
/// </summary>
|
|
||||||
public partial class ImportViewModel : ObservableObject
|
|
||||||
{
|
|
||||||
private readonly ParseService _parseService;
|
|
||||||
private readonly ILogger<ImportViewModel> _logger;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string _selectedPath = "";
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _isRecursive;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _isImporting;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private int _progressValue;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string _statusMessage = "请选择日志文件或目录";
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private ObservableCollection<ImportResultItem> _importResults = new();
|
|
||||||
|
|
||||||
public ImportViewModel(ParseService parseService, ILogger<ImportViewModel> logger)
|
|
||||||
{
|
|
||||||
_parseService = parseService;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
private void SelectFile()
|
|
||||||
{
|
|
||||||
var dialog = new OpenFileDialog
|
|
||||||
{
|
|
||||||
Title = "选择日志文件",
|
|
||||||
Filter = "日志文件 (*.log)|*.log|所有文件 (*.*)|*.*",
|
|
||||||
Multiselect = false
|
|
||||||
};
|
|
||||||
|
|
||||||
if (dialog.ShowDialog() == true)
|
|
||||||
{
|
|
||||||
SelectedPath = dialog.FileName;
|
|
||||||
StatusMessage = $"已选择文件: {System.IO.Path.GetFileName(SelectedPath)}";
|
|
||||||
_logger.LogDebug("用户选择文件: {FilePath}", SelectedPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
private void SelectFolder()
|
|
||||||
{
|
|
||||||
var dialog = new OpenFolderDialog
|
|
||||||
{
|
|
||||||
Title = "选择日志目录",
|
|
||||||
Multiselect = false
|
|
||||||
};
|
|
||||||
|
|
||||||
if (dialog.ShowDialog() == true)
|
|
||||||
{
|
|
||||||
SelectedPath = dialog.FolderName;
|
|
||||||
StatusMessage = $"已选择目录: {System.IO.Path.GetFileName(SelectedPath)}";
|
|
||||||
_logger.LogDebug("用户选择目录: {FolderPath}, 递归={IsRecursive}", SelectedPath, IsRecursive);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
private async Task ImportAsync()
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(SelectedPath))
|
|
||||||
{
|
|
||||||
StatusMessage = "请先选择文件或目录";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
IsImporting = true;
|
|
||||||
ImportResults.Clear();
|
|
||||||
StatusMessage = "正在导入...";
|
|
||||||
|
|
||||||
_logger.LogInformation("开始导入: {Path}, 递归={IsRecursive}", SelectedPath, IsRecursive);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (System.IO.File.Exists(SelectedPath))
|
|
||||||
{
|
|
||||||
// 导入单个文件
|
|
||||||
var report = await _parseService.ParseFileAsync(SelectedPath);
|
|
||||||
ImportResults.Add(new ImportResultItem(report));
|
|
||||||
StatusMessage = $"导入完成: Qfod={report.QfodCount}, Ploss={report.PlossCount}, 错误={report.ErrorCount}";
|
|
||||||
_logger.LogInformation("单文件导入完成: {FileName}, Qfod={Qfod}, Ploss={Ploss}, 错误={Errors}",
|
|
||||||
report.FileName, report.QfodCount, report.PlossCount, report.ErrorCount);
|
|
||||||
|
|
||||||
// 发送导入完成消息,通知其他 ViewModel 刷新数据
|
|
||||||
WeakReferenceMessenger.Default.Send(new DataImportedMessage(1));
|
|
||||||
}
|
|
||||||
else if (System.IO.Directory.Exists(SelectedPath))
|
|
||||||
{
|
|
||||||
// 导入目录
|
|
||||||
var reports = await _parseService.ParseDirectoryAsync(SelectedPath, IsRecursive);
|
|
||||||
|
|
||||||
int totalQfod = 0, totalPloss = 0, totalErrors = 0;
|
|
||||||
foreach (var report in reports)
|
|
||||||
{
|
|
||||||
ImportResults.Add(new ImportResultItem(report));
|
|
||||||
totalQfod += report.QfodCount;
|
|
||||||
totalPloss += report.PlossCount;
|
|
||||||
totalErrors += report.ErrorCount;
|
|
||||||
ProgressValue = (int)((double)ImportResults.Count / reports.Count * 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusMessage = $"导入完成: {reports.Count} 个文件, Qfod={totalQfod}, Ploss={totalPloss}, 错误={totalErrors}";
|
|
||||||
_logger.LogInformation("目录导入完成: {FileCount} 个文件, Qfod={Qfod}, Ploss={Ploss}, 错误={Errors}",
|
|
||||||
reports.Count, totalQfod, totalPloss, totalErrors);
|
|
||||||
|
|
||||||
// 发送导入完成消息,通知其他 ViewModel 刷新数据
|
|
||||||
WeakReferenceMessenger.Default.Send(new DataImportedMessage(reports.Count));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StatusMessage = "路径不存在";
|
|
||||||
_logger.LogWarning("导入路径不存在: {Path}", SelectedPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
StatusMessage = $"导入失败: {ex.Message}";
|
|
||||||
_logger.LogError(ex, "导入失败: {Path}", SelectedPath);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
IsImporting = false;
|
|
||||||
ProgressValue = 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 导入结果项
|
|
||||||
/// </summary>
|
|
||||||
public class ImportResultItem
|
|
||||||
{
|
|
||||||
public string FileName { get; }
|
|
||||||
public int QfodCount { get; }
|
|
||||||
public int PlossCount { get; }
|
|
||||||
public int ErrorCount { get; }
|
|
||||||
public string Status { get; }
|
|
||||||
public bool IsSuccess { get; }
|
|
||||||
|
|
||||||
public ImportResultItem(ParseReport report)
|
|
||||||
{
|
|
||||||
FileName = report.FileName;
|
|
||||||
QfodCount = report.QfodCount;
|
|
||||||
PlossCount = report.PlossCount;
|
|
||||||
ErrorCount = report.ErrorCount;
|
|
||||||
IsSuccess = report.IsSuccess;
|
|
||||||
Status = report.IsSuccess ? "成功" : report.ErrorMessage ?? "失败";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,174 +0,0 @@
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
|
||||||
using CommunityToolkit.Mvvm.Input;
|
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using System.Windows;
|
|
||||||
using WCTDataMiner.Core.Services;
|
|
||||||
using WCTDataMiner.Wpf.Messages;
|
|
||||||
|
|
||||||
namespace WCTDataMiner.Wpf.ViewModels;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 主窗口 ViewModel - 导航控制
|
|
||||||
/// </summary>
|
|
||||||
public partial class MainViewModel : ObservableObject,
|
|
||||||
IRecipient<NavigateToPlossChartMessage>,
|
|
||||||
IRecipient<NavigateToQfodChartMessage>,
|
|
||||||
IRecipient<NavigateToPlossTableMessage>,
|
|
||||||
IRecipient<NavigateToQfodTableMessage>
|
|
||||||
{
|
|
||||||
private readonly ImportViewModel _importViewModel;
|
|
||||||
private readonly ScenarioListViewModel _scenarioListViewModel;
|
|
||||||
private readonly IServiceProvider _serviceProvider;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private ObservableObject _currentView = null!;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string? _selectedTxPanel;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string? _selectedTxHardware;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string? _selectedTxSoftware;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string? _selectedRxType;
|
|
||||||
|
|
||||||
// 筛选选项列表(动态加载)
|
|
||||||
[ObservableProperty]
|
|
||||||
private List<string> _txPanels = new() { FilterConstants.AllOption };
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private List<string> _txHardwares = new() { FilterConstants.AllOption };
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private List<string> _txSoftwares = new() { FilterConstants.AllOption };
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private List<string> _rxTypes = new() { FilterConstants.AllOption };
|
|
||||||
|
|
||||||
public MainViewModel(
|
|
||||||
ImportViewModel importViewModel,
|
|
||||||
ScenarioListViewModel scenarioListViewModel,
|
|
||||||
IServiceProvider serviceProvider)
|
|
||||||
{
|
|
||||||
_importViewModel = importViewModel;
|
|
||||||
_scenarioListViewModel = scenarioListViewModel;
|
|
||||||
_serviceProvider = serviceProvider;
|
|
||||||
_currentView = _scenarioListViewModel;
|
|
||||||
|
|
||||||
// 注册导航消息订阅
|
|
||||||
WeakReferenceMessenger.Default.Register<NavigateToPlossChartMessage>(this);
|
|
||||||
WeakReferenceMessenger.Default.Register<NavigateToQfodChartMessage>(this);
|
|
||||||
WeakReferenceMessenger.Default.Register<NavigateToPlossTableMessage>(this);
|
|
||||||
WeakReferenceMessenger.Default.Register<NavigateToQfodTableMessage>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 初始化加载场景数据和筛选选项
|
|
||||||
/// </summary>
|
|
||||||
public async Task InitializeAsync()
|
|
||||||
{
|
|
||||||
// 加载筛选选项
|
|
||||||
var filterOptions = await _scenarioListViewModel.GetFilterOptionsAsync();
|
|
||||||
TxPanels = filterOptions.TxPanels;
|
|
||||||
TxHardwares = filterOptions.TxHardwares;
|
|
||||||
TxSoftwares = filterOptions.TxSoftwares;
|
|
||||||
RxTypes = filterOptions.RxTypes;
|
|
||||||
|
|
||||||
// 加载场景列表
|
|
||||||
await _scenarioListViewModel.LoadScenariosAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
private void NavigateToImport()
|
|
||||||
{
|
|
||||||
CurrentView = _importViewModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
private async Task NavigateToScenarios()
|
|
||||||
{
|
|
||||||
CurrentView = _scenarioListViewModel;
|
|
||||||
await _scenarioListViewModel.LoadScenariosAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
private void NavigateToPlossChart(Guid scenarioId)
|
|
||||||
{
|
|
||||||
var vm = _serviceProvider.GetRequiredService<PlossChartViewModel>();
|
|
||||||
vm.ScenarioId = scenarioId;
|
|
||||||
CurrentView = vm;
|
|
||||||
}
|
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
private void NavigateToQfodChart(Guid scenarioId)
|
|
||||||
{
|
|
||||||
var vm = _serviceProvider.GetRequiredService<QfodChartViewModel>();
|
|
||||||
vm.ScenarioId = scenarioId;
|
|
||||||
CurrentView = vm;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 应用筛选条件并刷新场景列表
|
|
||||||
/// </summary>
|
|
||||||
public async Task ApplyFilterAsync()
|
|
||||||
{
|
|
||||||
await _scenarioListViewModel.LoadScenariosByFilterAsync(
|
|
||||||
SelectedTxPanel, SelectedTxHardware, SelectedTxSoftware, SelectedRxType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 接收导航到 Ploss 图表消息
|
|
||||||
/// </summary>
|
|
||||||
public void Receive(NavigateToPlossChartMessage message)
|
|
||||||
{
|
|
||||||
Application.Current.Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
var vm = _serviceProvider.GetRequiredService<PlossChartViewModel>();
|
|
||||||
vm.ScenarioId = message.ScenarioId;
|
|
||||||
CurrentView = vm;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 接收导航到 Qfod 图表消息
|
|
||||||
/// </summary>
|
|
||||||
public void Receive(NavigateToQfodChartMessage message)
|
|
||||||
{
|
|
||||||
Application.Current.Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
var vm = _serviceProvider.GetRequiredService<QfodChartViewModel>();
|
|
||||||
vm.ScenarioId = message.ScenarioId;
|
|
||||||
CurrentView = vm;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 接收导航到 Ploss 表格消息
|
|
||||||
/// </summary>
|
|
||||||
public void Receive(NavigateToPlossTableMessage message)
|
|
||||||
{
|
|
||||||
Application.Current.Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
var vm = _serviceProvider.GetRequiredService<PlossTableViewModel>();
|
|
||||||
vm.ScenarioId = message.ScenarioId;
|
|
||||||
CurrentView = vm;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 接收导航到 Qfod 表格消息
|
|
||||||
/// </summary>
|
|
||||||
public void Receive(NavigateToQfodTableMessage message)
|
|
||||||
{
|
|
||||||
Application.Current.Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
var vm = _serviceProvider.GetRequiredService<QfodTableViewModel>();
|
|
||||||
vm.ScenarioId = message.ScenarioId;
|
|
||||||
CurrentView = vm;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
|
||||||
using CommunityToolkit.Mvvm.Input;
|
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
|
||||||
using LiveChartsCore;
|
|
||||||
using LiveChartsCore.SkiaSharpView;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using WCTDataMiner.Core.Services;
|
|
||||||
using WCTDataMiner.Wpf.Messages;
|
|
||||||
|
|
||||||
namespace WCTDataMiner.Wpf.ViewModels;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ploss 折线图 ViewModel
|
|
||||||
/// </summary>
|
|
||||||
public partial class PlossChartViewModel : ObservableObject
|
|
||||||
{
|
|
||||||
private readonly ScenarioService _scenarioService;
|
|
||||||
private readonly ILogger<PlossChartViewModel> _logger;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private Guid _scenarioId;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private ISeries[] _series;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private Axis[] _xAxes;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private Axis[] _yAxes;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _isLoading;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string _loadingMessage = "";
|
|
||||||
|
|
||||||
public PlossChartViewModel(
|
|
||||||
ScenarioService scenarioService,
|
|
||||||
ILogger<PlossChartViewModel> logger)
|
|
||||||
{
|
|
||||||
_scenarioService = scenarioService;
|
|
||||||
_logger = logger;
|
|
||||||
|
|
||||||
// 初始化图表配置
|
|
||||||
Series = Array.Empty<ISeries>();
|
|
||||||
XAxes = new Axis[] { new Axis { Name = "Trigger Count" } };
|
|
||||||
YAxes = new Axis[] { new Axis { Name = "Power Loss (mW)" } };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ScenarioId 属性变更时自动触发数据加载
|
|
||||||
/// </summary>
|
|
||||||
partial void OnScenarioIdChanged(Guid value)
|
|
||||||
{
|
|
||||||
if (value != Guid.Empty)
|
|
||||||
{
|
|
||||||
_ = LoadDataAsync().ContinueWith(t =>
|
|
||||||
{
|
|
||||||
if (t.Exception != null)
|
|
||||||
{
|
|
||||||
_logger.LogError(t.Exception, "LoadDataAsync 失败: ScenarioId={ScenarioId}", value);
|
|
||||||
}
|
|
||||||
}, TaskContinuationOptions.OnlyOnFaulted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
private void SwitchToTable()
|
|
||||||
{
|
|
||||||
WeakReferenceMessenger.Default.Send(new NavigateToPlossTableMessage(ScenarioId));
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task LoadDataAsync()
|
|
||||||
{
|
|
||||||
if (IsLoading) return; // 防并发
|
|
||||||
|
|
||||||
IsLoading = true;
|
|
||||||
LoadingMessage = "正在加载数据...";
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var records = await _scenarioService.GetPlossRecordsByScenarioIdAsync(ScenarioId);
|
|
||||||
|
|
||||||
if (records.Count == 0)
|
|
||||||
{
|
|
||||||
Series = Array.Empty<ISeries>();
|
|
||||||
_logger.LogWarning("未找到 Ploss 数据: ScenarioId={ScenarioId}", ScenarioId);
|
|
||||||
LoadingMessage = "无数据";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 构建 Ploss 曲线 (Field9) 和 Threshold 阈值线 (Field10)
|
|
||||||
var plossValues = records.Select(r => (double)r.Field9).ToArray();
|
|
||||||
var thresholdValues = records.Select(r => (double)r.Field10).ToArray();
|
|
||||||
var triggerLabels = records.Select(r => r.Field11.ToString()).ToArray();
|
|
||||||
|
|
||||||
Series = new ISeries[]
|
|
||||||
{
|
|
||||||
new LineSeries<double>
|
|
||||||
{
|
|
||||||
Name = "Ploss",
|
|
||||||
Values = plossValues,
|
|
||||||
Fill = null,
|
|
||||||
GeometrySize = 5
|
|
||||||
},
|
|
||||||
new LineSeries<double>
|
|
||||||
{
|
|
||||||
Name = "Threshold",
|
|
||||||
Values = thresholdValues,
|
|
||||||
Fill = null,
|
|
||||||
GeometrySize = 0,
|
|
||||||
LineSmoothness = 0 // 直线
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 更新 X 轴标签
|
|
||||||
XAxes = new Axis[]
|
|
||||||
{
|
|
||||||
new Axis
|
|
||||||
{
|
|
||||||
Name = "Trigger Count",
|
|
||||||
Labels = triggerLabels
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
_logger.LogInformation("加载 Ploss 图表数据成功: ScenarioId={ScenarioId}, 记录数={Count}", ScenarioId, records.Count);
|
|
||||||
LoadingMessage = "";
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "加载 Ploss 图表数据失败: ScenarioId={ScenarioId}", ScenarioId);
|
|
||||||
LoadingMessage = $"加载失败: {ex.Message}";
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
IsLoading = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
|
||||||
using CommunityToolkit.Mvvm.Input;
|
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using WCTDataMiner.Core.Models;
|
|
||||||
using WCTDataMiner.Core.Services;
|
|
||||||
using WCTDataMiner.Wpf.Messages;
|
|
||||||
|
|
||||||
namespace WCTDataMiner.Wpf.ViewModels;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ploss 数据表格 ViewModel
|
|
||||||
/// </summary>
|
|
||||||
public partial class PlossTableViewModel : ObservableObject
|
|
||||||
{
|
|
||||||
private readonly ScenarioService _scenarioService;
|
|
||||||
private readonly ILogger<PlossTableViewModel> _logger;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private Guid _scenarioId;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private ObservableCollection<PlossRecord> _records = new();
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _isLoading;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string _loadingMessage = "";
|
|
||||||
|
|
||||||
public PlossTableViewModel(
|
|
||||||
ScenarioService scenarioService,
|
|
||||||
ILogger<PlossTableViewModel> logger)
|
|
||||||
{
|
|
||||||
_scenarioService = scenarioService;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ScenarioId 属性变更时自动触发数据加载
|
|
||||||
/// </summary>
|
|
||||||
partial void OnScenarioIdChanged(Guid value)
|
|
||||||
{
|
|
||||||
if (value != Guid.Empty)
|
|
||||||
{
|
|
||||||
_ = LoadDataAsync().ContinueWith(t =>
|
|
||||||
{
|
|
||||||
if (t.Exception != null)
|
|
||||||
{
|
|
||||||
_logger.LogError(t.Exception, "LoadDataAsync 失败: ScenarioId={ScenarioId}", value);
|
|
||||||
}
|
|
||||||
}, TaskContinuationOptions.OnlyOnFaulted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task LoadDataAsync()
|
|
||||||
{
|
|
||||||
if (IsLoading) return; // 防并发
|
|
||||||
|
|
||||||
IsLoading = true;
|
|
||||||
LoadingMessage = "正在加载数据...";
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var records = await _scenarioService.GetPlossRecordsByScenarioIdAsync(ScenarioId);
|
|
||||||
Records = new ObservableCollection<PlossRecord>(records);
|
|
||||||
_logger.LogInformation("加载 Ploss 表格数据成功: ScenarioId={ScenarioId}, 记录数={Count}", ScenarioId, records.Count);
|
|
||||||
LoadingMessage = "";
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "加载 Ploss 表格数据失败: ScenarioId={ScenarioId}", ScenarioId);
|
|
||||||
LoadingMessage = $"加载失败: {ex.Message}";
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
IsLoading = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
private void SwitchToChart()
|
|
||||||
{
|
|
||||||
WeakReferenceMessenger.Default.Send(new NavigateToPlossChartMessage(ScenarioId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
|
||||||
using CommunityToolkit.Mvvm.Input;
|
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
|
||||||
using LiveChartsCore;
|
|
||||||
using LiveChartsCore.SkiaSharpView;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using WCTDataMiner.Core.Services;
|
|
||||||
using WCTDataMiner.Wpf.Messages;
|
|
||||||
|
|
||||||
namespace WCTDataMiner.Wpf.ViewModels;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Qfod 折线图 ViewModel
|
|
||||||
/// </summary>
|
|
||||||
public partial class QfodChartViewModel : ObservableObject
|
|
||||||
{
|
|
||||||
private readonly ScenarioService _scenarioService;
|
|
||||||
private readonly ILogger<QfodChartViewModel> _logger;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private Guid _scenarioId;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private ISeries[] _series;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private Axis[] _xAxes;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private Axis[] _yAxes;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _isLoading;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string _loadingMessage = "";
|
|
||||||
|
|
||||||
public QfodChartViewModel(
|
|
||||||
ScenarioService scenarioService,
|
|
||||||
ILogger<QfodChartViewModel> logger)
|
|
||||||
{
|
|
||||||
_scenarioService = scenarioService;
|
|
||||||
_logger = logger;
|
|
||||||
|
|
||||||
// 初始化图表配置
|
|
||||||
Series = Array.Empty<ISeries>();
|
|
||||||
XAxes = new Axis[] { new Axis { Name = "Coil Index" } };
|
|
||||||
YAxes = new Axis[] { new Axis { Name = "Q Value" } };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ScenarioId 属性变更时自动触发数据加载
|
|
||||||
/// </summary>
|
|
||||||
partial void OnScenarioIdChanged(Guid value)
|
|
||||||
{
|
|
||||||
if (value != Guid.Empty)
|
|
||||||
{
|
|
||||||
_ = LoadDataAsync().ContinueWith(t =>
|
|
||||||
{
|
|
||||||
if (t.Exception != null)
|
|
||||||
{
|
|
||||||
_logger.LogError(t.Exception, "LoadDataAsync 失败: ScenarioId={ScenarioId}", value);
|
|
||||||
}
|
|
||||||
}, TaskContinuationOptions.OnlyOnFaulted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
private void SwitchToTable()
|
|
||||||
{
|
|
||||||
WeakReferenceMessenger.Default.Send(new NavigateToQfodTableMessage(ScenarioId));
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task LoadDataAsync()
|
|
||||||
{
|
|
||||||
if (IsLoading) return; // 防并发
|
|
||||||
|
|
||||||
IsLoading = true;
|
|
||||||
LoadingMessage = "正在加载数据...";
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var records = await _scenarioService.GetQfodRecordsByScenarioIdAsync(ScenarioId);
|
|
||||||
|
|
||||||
if (records.Count == 0)
|
|
||||||
{
|
|
||||||
Series = Array.Empty<ISeries>();
|
|
||||||
_logger.LogWarning("未找到 Qfod 数据: ScenarioId={ScenarioId}", ScenarioId);
|
|
||||||
LoadingMessage = "无数据";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 构建 DeltaQ、CurrentQ、RawQ 三条曲线
|
|
||||||
var deltaQValues = records.Select(r => (double)r.DeltaQ).ToArray();
|
|
||||||
var currentQValues = records.Select(r => (double)r.CurrentQ).ToArray();
|
|
||||||
var rawQValues = records.Select(r => (double)r.RawQ).ToArray();
|
|
||||||
var coilLabels = records.Select(r => $"{r.ChargerIndex}-{r.CoilIndex}").ToArray();
|
|
||||||
|
|
||||||
Series = new ISeries[]
|
|
||||||
{
|
|
||||||
new LineSeries<double>
|
|
||||||
{
|
|
||||||
Name = "DeltaQ",
|
|
||||||
Values = deltaQValues,
|
|
||||||
GeometrySize = 5
|
|
||||||
},
|
|
||||||
new LineSeries<double>
|
|
||||||
{
|
|
||||||
Name = "CurrentQ",
|
|
||||||
Values = currentQValues,
|
|
||||||
GeometrySize = 5
|
|
||||||
},
|
|
||||||
new LineSeries<double>
|
|
||||||
{
|
|
||||||
Name = "RawQ",
|
|
||||||
Values = rawQValues,
|
|
||||||
GeometrySize = 5
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 更新 X 轴标签
|
|
||||||
XAxes = new Axis[]
|
|
||||||
{
|
|
||||||
new Axis
|
|
||||||
{
|
|
||||||
Name = "Charger-Coil Index",
|
|
||||||
Labels = coilLabels
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
_logger.LogInformation("加载 Qfod 图表数据成功: ScenarioId={ScenarioId}, 记录数={Count}", ScenarioId, records.Count);
|
|
||||||
LoadingMessage = "";
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "加载 Qfod 图表数据失败: ScenarioId={ScenarioId}", ScenarioId);
|
|
||||||
LoadingMessage = $"加载失败: {ex.Message}";
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
IsLoading = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
|
||||||
using CommunityToolkit.Mvvm.Input;
|
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using WCTDataMiner.Core.Models;
|
|
||||||
using WCTDataMiner.Core.Services;
|
|
||||||
using WCTDataMiner.Wpf.Messages;
|
|
||||||
|
|
||||||
namespace WCTDataMiner.Wpf.ViewModels;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Qfod 数据表格 ViewModel
|
|
||||||
/// </summary>
|
|
||||||
public partial class QfodTableViewModel : ObservableObject
|
|
||||||
{
|
|
||||||
private readonly ScenarioService _scenarioService;
|
|
||||||
private readonly ILogger<QfodTableViewModel> _logger;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private Guid _scenarioId;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private ObservableCollection<QfodRecord> _records = new();
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _isLoading;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string _loadingMessage = "";
|
|
||||||
|
|
||||||
public QfodTableViewModel(
|
|
||||||
ScenarioService scenarioService,
|
|
||||||
ILogger<QfodTableViewModel> logger)
|
|
||||||
{
|
|
||||||
_scenarioService = scenarioService;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ScenarioId 属性变更时自动触发数据加载
|
|
||||||
/// </summary>
|
|
||||||
partial void OnScenarioIdChanged(Guid value)
|
|
||||||
{
|
|
||||||
if (value != Guid.Empty)
|
|
||||||
{
|
|
||||||
_ = LoadDataAsync().ContinueWith(t =>
|
|
||||||
{
|
|
||||||
if (t.Exception != null)
|
|
||||||
{
|
|
||||||
_logger.LogError(t.Exception, "LoadDataAsync 失败: ScenarioId={ScenarioId}", value);
|
|
||||||
}
|
|
||||||
}, TaskContinuationOptions.OnlyOnFaulted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task LoadDataAsync()
|
|
||||||
{
|
|
||||||
if (IsLoading) return; // 防并发
|
|
||||||
|
|
||||||
IsLoading = true;
|
|
||||||
LoadingMessage = "正在加载数据...";
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var records = await _scenarioService.GetQfodRecordsByScenarioIdAsync(ScenarioId);
|
|
||||||
Records = new ObservableCollection<QfodRecord>(records);
|
|
||||||
_logger.LogInformation("加载 Qfod 表格数据成功: ScenarioId={ScenarioId}, 记录数={Count}", ScenarioId, records.Count);
|
|
||||||
LoadingMessage = "";
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "加载 Qfod 表格数据失败: ScenarioId={ScenarioId}", ScenarioId);
|
|
||||||
LoadingMessage = $"加载失败: {ex.Message}";
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
IsLoading = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
private void SwitchToChart()
|
|
||||||
{
|
|
||||||
WeakReferenceMessenger.Default.Send(new NavigateToQfodChartMessage(ScenarioId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,177 +0,0 @@
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using WCTDataMiner.Core.Services;
|
|
||||||
using WCTDataMiner.Wpf.Messages;
|
|
||||||
|
|
||||||
namespace WCTDataMiner.Wpf.ViewModels;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 场景列表 ViewModel
|
|
||||||
/// </summary>
|
|
||||||
public partial class ScenarioListViewModel : ObservableObject, IRecipient<DataImportedMessage>
|
|
||||||
{
|
|
||||||
private readonly ScenarioService _scenarioService;
|
|
||||||
private readonly ILogger<ScenarioListViewModel> _logger;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private ObservableCollection<ScenarioItem> _scenarios = new();
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private ScenarioItem? _selectedScenario;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _isLoading;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string _loadingMessage = "";
|
|
||||||
|
|
||||||
public ScenarioListViewModel(
|
|
||||||
ScenarioService scenarioService,
|
|
||||||
ILogger<ScenarioListViewModel> logger)
|
|
||||||
{
|
|
||||||
_scenarioService = scenarioService;
|
|
||||||
_logger = logger;
|
|
||||||
|
|
||||||
// 注册消息订阅,接收导入完成通知
|
|
||||||
WeakReferenceMessenger.Default.Register<DataImportedMessage>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 从数据库加载场景列表
|
|
||||||
/// </summary>
|
|
||||||
public async Task LoadScenariosAsync()
|
|
||||||
{
|
|
||||||
// 避免并发加载
|
|
||||||
if (IsLoading)
|
|
||||||
{
|
|
||||||
_logger.LogWarning("跳过重复加载请求:当前正在加载");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
IsLoading = true;
|
|
||||||
LoadingMessage = "正在加载场景列表...";
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var scenarios = await _scenarioService.GetAllScenariosAsync();
|
|
||||||
|
|
||||||
// 批量更新,避免逐项 Add 导致频繁 UI 刷新
|
|
||||||
var items = scenarios.Select(s => new ScenarioItem
|
|
||||||
{
|
|
||||||
Id = s.Id,
|
|
||||||
TxPanel = s.TxPanel?.Name ?? "",
|
|
||||||
TxHardware = s.TxHardware?.Version ?? "",
|
|
||||||
TxSoftware = s.TxSoftware?.Version ?? "",
|
|
||||||
RxType = s.RxType?.Name ?? "",
|
|
||||||
TestDate = s.TestDate.ToString("yyyy-MM-dd"),
|
|
||||||
QfodCount = s.QfodCount,
|
|
||||||
PlossCount = s.PlossCount
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
Scenarios = new ObservableCollection<ScenarioItem>(items);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "加载场景列表失败");
|
|
||||||
LoadingMessage = $"加载失败: {ex.Message}";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
IsLoading = false;
|
|
||||||
LoadingMessage = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 根据筛选条件加载场景
|
|
||||||
/// </summary>
|
|
||||||
public async Task LoadScenariosByFilterAsync(
|
|
||||||
string? txPanel = null,
|
|
||||||
string? txHardware = null,
|
|
||||||
string? txSoftware = null,
|
|
||||||
string? rxType = null)
|
|
||||||
{
|
|
||||||
// 避免并发加载
|
|
||||||
if (IsLoading)
|
|
||||||
{
|
|
||||||
_logger.LogWarning("跳过重复筛选请求:当前正在加载");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
IsLoading = true;
|
|
||||||
LoadingMessage = "正在筛选场景...";
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var scenarios = await _scenarioService.GetScenariosByFilterAsync(
|
|
||||||
txPanel, txHardware, txSoftware, rxType);
|
|
||||||
|
|
||||||
// 批量更新,避免逐项 Add 导致频繁 UI 刷新
|
|
||||||
var items = scenarios.Select(s => new ScenarioItem
|
|
||||||
{
|
|
||||||
Id = s.Id,
|
|
||||||
TxPanel = s.TxPanel?.Name ?? "",
|
|
||||||
TxHardware = s.TxHardware?.Version ?? "",
|
|
||||||
TxSoftware = s.TxSoftware?.Version ?? "",
|
|
||||||
RxType = s.RxType?.Name ?? "",
|
|
||||||
TestDate = s.TestDate.ToString("yyyy-MM-dd"),
|
|
||||||
QfodCount = s.QfodCount,
|
|
||||||
PlossCount = s.PlossCount
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
Scenarios = new ObservableCollection<ScenarioItem>(items);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "筛选场景失败");
|
|
||||||
LoadingMessage = $"筛选失败: {ex.Message}";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
IsLoading = false;
|
|
||||||
LoadingMessage = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 接收数据导入完成消息,自动刷新列表
|
|
||||||
/// </summary>
|
|
||||||
public async void Receive(DataImportedMessage message)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await LoadScenariosAsync();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "接收数据导入消息后刷新场景列表失败");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取可用的筛选选项
|
|
||||||
/// </summary>
|
|
||||||
public async Task<FilterOptions> GetFilterOptionsAsync()
|
|
||||||
{
|
|
||||||
return await _scenarioService.GetFilterOptionsAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 场景项数据模型
|
|
||||||
/// </summary>
|
|
||||||
public class ScenarioItem
|
|
||||||
{
|
|
||||||
public Guid Id { get; set; }
|
|
||||||
public string TxPanel { get; set; } = "";
|
|
||||||
public string TxHardware { get; set; } = "";
|
|
||||||
public string TxSoftware { get; set; } = "";
|
|
||||||
public string RxType { get; set; } = "";
|
|
||||||
public string TestDate { get; set; } = "";
|
|
||||||
public int QfodCount { get; set; }
|
|
||||||
public int PlossCount { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
<UserControl x:Class="WCTDataMiner.Wpf.Views.ImportView"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:local="clr-namespace:WCTDataMiner.Wpf.Views"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
d:DesignHeight="450" d:DesignWidth="600">
|
|
||||||
<Grid Margin="20">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition Height="*"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
|
|
||||||
<!-- 标题 -->
|
|
||||||
<TextBlock Grid.Row="0" Text="数据导入" FontSize="20" FontWeight="Bold" Margin="0,0,0,20"/>
|
|
||||||
|
|
||||||
<!-- 选择路径 -->
|
|
||||||
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,0,0,15">
|
|
||||||
<Button Content="选择文件" Command="{Binding SelectFileCommand}"
|
|
||||||
Width="100" Margin="0,0,10,0" Padding="10,5"/>
|
|
||||||
<Button Content="选择目录" Command="{Binding SelectFolderCommand}"
|
|
||||||
Width="100" Margin="0,0,10,0" Padding="10,5"/>
|
|
||||||
<TextBox Text="{Binding SelectedPath, UpdateSourceTrigger=PropertyChanged}"
|
|
||||||
Width="300" IsReadOnly="True" VerticalContentAlignment="Center"/>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<!-- 选项和导入按钮 -->
|
|
||||||
<StackPanel Grid.Row="2" Orientation="Horizontal" Margin="0,0,0,15">
|
|
||||||
<CheckBox Content="递归搜索子目录" IsChecked="{Binding IsRecursive}"
|
|
||||||
Margin="0,0,20,0" VerticalContentAlignment="Center"/>
|
|
||||||
<Button Content="开始导入" Command="{Binding ImportCommand}"
|
|
||||||
Width="120" Padding="15,8" FontWeight="Bold"
|
|
||||||
IsEnabled="{Binding IsImporting, Converter={StaticResource InverseBooleanConverter}}"/>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<!-- 进度和状态 -->
|
|
||||||
<StackPanel Grid.Row="3" Margin="0,0,0,15">
|
|
||||||
<ProgressBar Height="20" Value="{Binding ProgressValue}" Maximum="100"
|
|
||||||
Visibility="{Binding IsImporting, Converter={StaticResource BooleanToVisibilityConverter}}"/>
|
|
||||||
<TextBlock Text="{Binding StatusMessage}" FontSize="14" Margin="0,5,0,0"/>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<!-- 导入结果列表 -->
|
|
||||||
<DataGrid Grid.Row="4" ItemsSource="{Binding ImportResults}"
|
|
||||||
AutoGenerateColumns="False"
|
|
||||||
IsReadOnly="True"
|
|
||||||
GridLinesVisibility="Horizontal"
|
|
||||||
AlternatingRowBackground="#F9F9F9"
|
|
||||||
CanUserAddRows="False">
|
|
||||||
<DataGrid.Columns>
|
|
||||||
<DataGridTextColumn Header="文件名" Binding="{Binding FileName}" Width="*"/>
|
|
||||||
<DataGridTextColumn Header="Qfod" Binding="{Binding QfodCount}" Width="80"/>
|
|
||||||
<DataGridTextColumn Header="Ploss" Binding="{Binding PlossCount}" Width="80"/>
|
|
||||||
<DataGridTextColumn Header="错误" Binding="{Binding ErrorCount}" Width="80"/>
|
|
||||||
<DataGridTextColumn Header="状态" Binding="{Binding Status}" Width="100"/>
|
|
||||||
</DataGrid.Columns>
|
|
||||||
</DataGrid>
|
|
||||||
</Grid>
|
|
||||||
</UserControl>
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
using System.Windows;
|
|
||||||
using System.Windows.Controls;
|
|
||||||
|
|
||||||
namespace WCTDataMiner.Wpf.Views;
|
|
||||||
|
|
||||||
public partial class ImportView : UserControl
|
|
||||||
{
|
|
||||||
public ImportView()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
<UserControl x:Class="WCTDataMiner.Wpf.Views.PlossChartView"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"
|
|
||||||
xmlns:local="clr-namespace:WCTDataMiner.Wpf.Views"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
d:DesignHeight="400" d:DesignWidth="600">
|
|
||||||
<Grid Margin="10">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition Height="*"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
|
|
||||||
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0,0,0,10">
|
|
||||||
<TextBlock Text="Ploss 功率损耗趋势图" FontSize="18" FontWeight="Bold"/>
|
|
||||||
<TextBlock Text="{Binding ScenarioId, StringFormat=' - 场景 {0}'}" FontSize="14" Foreground="Gray" Margin="10,5,0,0"/>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,0,0,10">
|
|
||||||
<Button Content="切换到表格" Command="{Binding SwitchToTableCommand}" Padding="10,5"/>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<lvc:CartesianChart Grid.Row="2"
|
|
||||||
Series="{Binding Series}"
|
|
||||||
XAxes="{Binding XAxes}"
|
|
||||||
YAxes="{Binding YAxes}"
|
|
||||||
LegendPosition="Bottom"
|
|
||||||
Background="White"/>
|
|
||||||
</Grid>
|
|
||||||
</UserControl>
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
using System.Windows.Controls;
|
|
||||||
|
|
||||||
namespace WCTDataMiner.Wpf.Views;
|
|
||||||
|
|
||||||
public partial class PlossChartView : UserControl
|
|
||||||
{
|
|
||||||
public PlossChartView()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
Loaded += async (s, e) =>
|
|
||||||
{
|
|
||||||
if (DataContext is ViewModels.PlossChartViewModel vm)
|
|
||||||
{
|
|
||||||
await vm.LoadDataAsync();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
<UserControl x:Class="WCTDataMiner.Wpf.Views.PlossTableView"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
d:DesignHeight="400" d:DesignWidth="900">
|
|
||||||
<Grid Margin="10">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition Height="*"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
|
|
||||||
<!-- 标题区域 -->
|
|
||||||
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0,0,0,10">
|
|
||||||
<TextBlock Text="Ploss 数据表格" FontSize="18" FontWeight="Bold"/>
|
|
||||||
<TextBlock Text="{Binding ScenarioId, StringFormat=' - 场景 {0}'}" FontSize="14" Foreground="Gray" Margin="10,5,0,0"/>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<!-- 操作按钮 -->
|
|
||||||
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,0,0,10">
|
|
||||||
<Button Content="切换到图表" Command="{Binding SwitchToChartCommand}" Padding="10,5" Margin="0,0,10,0"/>
|
|
||||||
<TextBlock Text="{Binding Records.Count, StringFormat='共 {0} 条记录'}" VerticalAlignment="Center" Foreground="Gray"/>
|
|
||||||
<!-- 加载状态/错误消息显示 -->
|
|
||||||
<TextBlock Text="{Binding LoadingMessage}" VerticalAlignment="Center" Foreground="Orange" Margin="20,0,0,0"/>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<!-- 数据表格 -->
|
|
||||||
<DataGrid Grid.Row="2"
|
|
||||||
ItemsSource="{Binding Records}"
|
|
||||||
AutoGenerateColumns="False"
|
|
||||||
IsReadOnly="True"
|
|
||||||
GridLinesVisibility="Horizontal"
|
|
||||||
AlternatingRowBackground="#F9F9F9"
|
|
||||||
CanUserAddRows="False"
|
|
||||||
HeadersVisibility="Column"
|
|
||||||
HorizontalScrollBarVisibility="Auto"
|
|
||||||
VirtualizingPanel.IsVirtualizing="True"
|
|
||||||
VirtualizingPanel.VirtualizationMode="Recycling"
|
|
||||||
EnableRowVirtualization="True"
|
|
||||||
EnableColumnVirtualization="True">
|
|
||||||
<DataGrid.Columns>
|
|
||||||
<DataGridTextColumn Header="PowLoss" Binding="{Binding PowLoss}" Width="80"/>
|
|
||||||
<DataGridTextColumn Header="DeltaP" Binding="{Binding DeltaP}" Width="80"/>
|
|
||||||
<DataGridTextColumn Header="RX_TYPE" Binding="{Binding Field1}" Width="80"/>
|
|
||||||
<DataGridTextColumn Header="Field2" Binding="{Binding Field2}" Width="70"/>
|
|
||||||
<DataGridTextColumn Header="Field3" Binding="{Binding Field3}" Width="70"/>
|
|
||||||
<DataGridTextColumn Header="RX power" Binding="{Binding Field4}" Width="80"/>
|
|
||||||
<DataGridTextColumn Header="TX power" Binding="{Binding Field5}" Width="80"/>
|
|
||||||
<DataGridTextColumn Header="Field6" Binding="{Binding Field6}" Width="70"/>
|
|
||||||
<DataGridTextColumn Header="Field7" Binding="{Binding Field7}" Width="80">
|
|
||||||
<DataGridTextColumn.ElementStyle>
|
|
||||||
<Style TargetType="TextBlock">
|
|
||||||
<Setter Property="Foreground" Value="Blue"/>
|
|
||||||
<Setter Property="FontWeight" Value="Bold"/>
|
|
||||||
</Style>
|
|
||||||
</DataGridTextColumn.ElementStyle>
|
|
||||||
</DataGridTextColumn>
|
|
||||||
<DataGridTextColumn Header="Field8" Binding="{Binding Field8}" Width="80">
|
|
||||||
<DataGridTextColumn.ElementStyle>
|
|
||||||
<Style TargetType="TextBlock">
|
|
||||||
<Setter Property="Foreground" Value="Red"/>
|
|
||||||
</Style>
|
|
||||||
</DataGridTextColumn.ElementStyle>
|
|
||||||
</DataGridTextColumn>
|
|
||||||
<DataGridTextColumn Header="ploss" Binding="{Binding Field9}" Width="70"/>
|
|
||||||
<DataGridTextColumn Header="threshold" Binding="{Binding Field10}" Width="80"/>
|
|
||||||
<DataGridTextColumn Header="Margin" Binding="{Binding Margin}" Width="80"/>
|
|
||||||
<DataGridTextColumn Header="触发次数" Binding="{Binding Field11}" Width="80"/>
|
|
||||||
<DataGridTextColumn Header="PFOD result" Binding="{Binding Field12}" Width="90"/>
|
|
||||||
<DataGridTextColumn Header="Field13" Binding="{Binding Field13}" Width="70"/>
|
|
||||||
<DataGridTextColumn Header="Field14" Binding="{Binding Field14}" Width="70"/>
|
|
||||||
<DataGridTextColumn Header="Field15" Binding="{Binding Field15}" Width="70"/>
|
|
||||||
<DataGridTextColumn Header="Field16" Binding="{Binding Field16}" Width="70"/>
|
|
||||||
</DataGrid.Columns>
|
|
||||||
</DataGrid>
|
|
||||||
</Grid>
|
|
||||||
</UserControl>
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using System.Windows.Controls;
|
|
||||||
|
|
||||||
namespace WCTDataMiner.Wpf.Views;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// PlossTableView.xaml 的交互逻辑
|
|
||||||
/// </summary>
|
|
||||||
public partial class PlossTableView : UserControl
|
|
||||||
{
|
|
||||||
public PlossTableView()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
<UserControl x:Class="WCTDataMiner.Wpf.Views.QfodChartView"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"
|
|
||||||
xmlns:local="clr-namespace:WCTDataMiner.Wpf.Views"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
d:DesignHeight="400" d:DesignWidth="600">
|
|
||||||
<Grid Margin="10">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition Height="*"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
|
|
||||||
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0,0,0,10">
|
|
||||||
<TextBlock Text="Qfod Q值变化图" FontSize="18" FontWeight="Bold"/>
|
|
||||||
<TextBlock Text="{Binding ScenarioId, StringFormat=' - 场景 {0}'}" FontSize="14" Foreground="Gray" Margin="10,5,0,0"/>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,0,0,10">
|
|
||||||
<Button Content="切换到表格" Command="{Binding SwitchToTableCommand}" Padding="10,5"/>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<lvc:CartesianChart Grid.Row="2"
|
|
||||||
Series="{Binding Series}"
|
|
||||||
XAxes="{Binding XAxes}"
|
|
||||||
YAxes="{Binding YAxes}"
|
|
||||||
LegendPosition="Bottom"
|
|
||||||
Background="White"/>
|
|
||||||
</Grid>
|
|
||||||
</UserControl>
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
using System.Windows.Controls;
|
|
||||||
|
|
||||||
namespace WCTDataMiner.Wpf.Views;
|
|
||||||
|
|
||||||
public partial class QfodChartView : UserControl
|
|
||||||
{
|
|
||||||
public QfodChartView()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
Loaded += async (s, e) =>
|
|
||||||
{
|
|
||||||
if (DataContext is ViewModels.QfodChartViewModel vm)
|
|
||||||
{
|
|
||||||
await vm.LoadDataAsync();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
<UserControl x:Class="WCTDataMiner.Wpf.Views.QfodTableView"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
d:DesignHeight="400" d:DesignWidth="600">
|
|
||||||
<Grid Margin="10">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition Height="*"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
|
|
||||||
<!-- 标题区域 -->
|
|
||||||
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0,0,0,10">
|
|
||||||
<TextBlock Text="Qfod 数据表格" FontSize="18" FontWeight="Bold"/>
|
|
||||||
<TextBlock Text="{Binding ScenarioId, StringFormat=' - 场景 {0}'}" FontSize="14" Foreground="Gray" Margin="10,5,0,0"/>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<!-- 操作按钮 -->
|
|
||||||
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,0,0,10">
|
|
||||||
<Button Content="切换到图表" Command="{Binding SwitchToChartCommand}" Padding="10,5" Margin="0,0,10,0"/>
|
|
||||||
<TextBlock Text="{Binding Records.Count, StringFormat='共 {0} 条记录'}" VerticalAlignment="Center" Foreground="Gray"/>
|
|
||||||
<!-- 加载状态/错误消息显示 -->
|
|
||||||
<TextBlock Text="{Binding LoadingMessage}" VerticalAlignment="Center" Foreground="Orange" Margin="20,0,0,0"/>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<!-- 数据表格 -->
|
|
||||||
<DataGrid Grid.Row="2"
|
|
||||||
ItemsSource="{Binding Records}"
|
|
||||||
AutoGenerateColumns="False"
|
|
||||||
IsReadOnly="True"
|
|
||||||
GridLinesVisibility="Horizontal"
|
|
||||||
AlternatingRowBackground="#F9F9F9"
|
|
||||||
CanUserAddRows="False"
|
|
||||||
HeadersVisibility="Column"
|
|
||||||
HorizontalScrollBarVisibility="Auto"
|
|
||||||
VirtualizingPanel.IsVirtualizing="True"
|
|
||||||
VirtualizingPanel.VirtualizationMode="Recycling"
|
|
||||||
EnableRowVirtualization="True"
|
|
||||||
EnableColumnVirtualization="True">
|
|
||||||
<DataGrid.Columns>
|
|
||||||
<DataGridTextColumn Header="ChargerIdx" Binding="{Binding ChargerIndex}" Width="100"/>
|
|
||||||
<DataGridTextColumn Header="CoilIdx" Binding="{Binding CoilIndex}" Width="80"/>
|
|
||||||
<DataGridTextColumn Header="DeltaQ" Binding="{Binding DeltaQ}" Width="80">
|
|
||||||
<DataGridTextColumn.ElementStyle>
|
|
||||||
<Style TargetType="TextBlock">
|
|
||||||
<Setter Property="Foreground" Value="Blue"/>
|
|
||||||
<Setter Property="FontWeight" Value="Bold"/>
|
|
||||||
</Style>
|
|
||||||
</DataGridTextColumn.ElementStyle>
|
|
||||||
</DataGridTextColumn>
|
|
||||||
<DataGridTextColumn Header="CurrentQ" Binding="{Binding CurrentQ}" Width="80"/>
|
|
||||||
<DataGridTextColumn Header="RawQ" Binding="{Binding RawQ}" Width="80"/>
|
|
||||||
<DataGridTextColumn Header="FodType" Binding="{Binding FodType}" Width="80"/>
|
|
||||||
<DataGridTextColumn Header="FieldF" Binding="{Binding FieldF}" Width="80"/>
|
|
||||||
</DataGrid.Columns>
|
|
||||||
</DataGrid>
|
|
||||||
</Grid>
|
|
||||||
</UserControl>
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using System.Windows.Controls;
|
|
||||||
|
|
||||||
namespace WCTDataMiner.Wpf.Views;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// QfodTableView.xaml 的交互逻辑
|
|
||||||
/// </summary>
|
|
||||||
public partial class QfodTableView : UserControl
|
|
||||||
{
|
|
||||||
public QfodTableView()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
<UserControl x:Class="WCTDataMiner.Wpf.Views.ScenarioListView"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:local="clr-namespace:WCTDataMiner.Wpf.Views"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
d:DesignHeight="400" d:DesignWidth="600">
|
|
||||||
<Grid Margin="10">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition Height="*"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
|
|
||||||
<TextBlock Grid.Row="0" Text="测试场景列表" FontSize="18" FontWeight="Bold" Margin="0,0,0,10"/>
|
|
||||||
|
|
||||||
<DataGrid Grid.Row="1" ItemsSource="{Binding Scenarios}"
|
|
||||||
SelectedItem="{Binding SelectedScenario}"
|
|
||||||
AutoGenerateColumns="False"
|
|
||||||
IsReadOnly="True"
|
|
||||||
GridLinesVisibility="Horizontal"
|
|
||||||
AlternatingRowBackground="#F9F9F9">
|
|
||||||
<DataGrid.Columns>
|
|
||||||
<DataGridTextColumn Header="TX 面板" Binding="{Binding TxPanel}" Width="*"/>
|
|
||||||
<DataGridTextColumn Header="TX 硬件" Binding="{Binding TxHardware}" Width="*"/>
|
|
||||||
<DataGridTextColumn Header="TX 软件" Binding="{Binding TxSoftware}" Width="*"/>
|
|
||||||
<DataGridTextColumn Header="RX 类型" Binding="{Binding RxType}" Width="*"/>
|
|
||||||
<DataGridTextColumn Header="测试日期" Binding="{Binding TestDate}" Width="*"/>
|
|
||||||
<DataGridTextColumn Header="Qfod 数量" Binding="{Binding QfodCount}" Width="80"/>
|
|
||||||
<DataGridTextColumn Header="Ploss 数量" Binding="{Binding PlossCount}" Width="80"/>
|
|
||||||
<DataGridTemplateColumn Header="操作" Width="150">
|
|
||||||
<DataGridTemplateColumn.CellTemplate>
|
|
||||||
<DataTemplate>
|
|
||||||
<StackPanel Orientation="Horizontal">
|
|
||||||
<Button Content="Ploss图" Margin="2" Padding="5,2"
|
|
||||||
Click="OnViewPlossChart"/>
|
|
||||||
<Button Content="Qfod图" Margin="2" Padding="5,2"
|
|
||||||
Click="OnViewQfodChart"/>
|
|
||||||
</StackPanel>
|
|
||||||
</DataTemplate>
|
|
||||||
</DataGridTemplateColumn.CellTemplate>
|
|
||||||
</DataGridTemplateColumn>
|
|
||||||
</DataGrid.Columns>
|
|
||||||
</DataGrid>
|
|
||||||
</Grid>
|
|
||||||
</UserControl>
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
using CommunityToolkit.Mvvm.Messaging;
|
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Controls;
|
|
||||||
using WCTDataMiner.Wpf.Messages;
|
|
||||||
using WCTDataMiner.Wpf.ViewModels;
|
|
||||||
|
|
||||||
namespace WCTDataMiner.Wpf.Views;
|
|
||||||
|
|
||||||
public partial class ScenarioListView : UserControl
|
|
||||||
{
|
|
||||||
public ScenarioListView()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnViewPlossChart(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
if (DataContext is ScenarioListViewModel vm && vm.SelectedScenario != null)
|
|
||||||
{
|
|
||||||
WeakReferenceMessenger.Default.Send(new NavigateToPlossChartMessage(vm.SelectedScenario.Id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnViewQfodChart(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
if (DataContext is ScenarioListViewModel vm && vm.SelectedScenario != null)
|
|
||||||
{
|
|
||||||
WeakReferenceMessenger.Default.Send(new NavigateToQfodChartMessage(vm.SelectedScenario.Id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>WinExe</OutputType>
|
|
||||||
<TargetFramework>net8.0-windows</TargetFramework>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<UseWPF>true</UseWPF>
|
|
||||||
<LangVersion>12.0</LangVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<!-- LiveCharts2 -->
|
|
||||||
<PackageReference Include="LiveChartsCore" Version="2.0.0-rc2" />
|
|
||||||
<PackageReference Include="LiveChartsCore.SkiaSharpView.WPF" Version="2.0.0-rc2" />
|
|
||||||
|
|
||||||
<!-- MVVM -->
|
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
|
||||||
|
|
||||||
<!-- DI -->
|
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
|
||||||
|
|
||||||
<!-- Logging -->
|
|
||||||
<PackageReference Include="Serilog" Version="4.0.0" />
|
|
||||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="8.0.0" />
|
|
||||||
<PackageReference Include="Serilog.Settings.Configuration" Version="8.0.0" />
|
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.0" />
|
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\WCTDataMiner.Core\WCTDataMiner.Core.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<None Update="appsettings.json">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
Reference in New Issue
Block a user