测试报告导出
This commit is contained in:
7
ADP.sln
7
ADP.sln
@@ -47,6 +47,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "加密狗", "加密狗\加
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CurveModule", "CurveModule\CurveModule.csproj", "{84006890-9288-44C4-9D17-FA88F3FDECFA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExportModule", "ExportModule\ExportModule.csproj", "{8923122F-F7D3-4AE7-9E86-9E78F1296A11}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -137,6 +139,10 @@ Global
|
||||
{84006890-9288-44C4-9D17-FA88F3FDECFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{84006890-9288-44C4-9D17-FA88F3FDECFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{84006890-9288-44C4-9D17-FA88F3FDECFA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8923122F-F7D3-4AE7-9E86-9E78F1296A11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8923122F-F7D3-4AE7-9E86-9E78F1296A11}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8923122F-F7D3-4AE7-9E86-9E78F1296A11}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8923122F-F7D3-4AE7-9E86-9E78F1296A11}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -152,5 +158,6 @@ Global
|
||||
{31F84D0E-3634-4C70-A830-21AF412E3BBF} = {1E92D601-68FC-45F6-8251-BD0F39226E5B}
|
||||
{AF2533DD-599D-49D7-942B-B0C26534D15F} = {1E92D601-68FC-45F6-8251-BD0F39226E5B}
|
||||
{84006890-9288-44C4-9D17-FA88F3FDECFA} = {1E92D601-68FC-45F6-8251-BD0F39226E5B}
|
||||
{8923122F-F7D3-4AE7-9E86-9E78F1296A11} = {1E92D601-68FC-45F6-8251-BD0F39226E5B}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -22,8 +22,10 @@
|
||||
<ProjectReference Include="..\BenchMovementModule\BenchMovementModule.csproj" />
|
||||
<ProjectReference Include="..\CANModule\CANModule.csproj" />
|
||||
<ProjectReference Include="..\Command\Command.csproj" />
|
||||
<ProjectReference Include="..\CurveModule\CurveModule.csproj" />
|
||||
<ProjectReference Include="..\DeviceCommand\DeviceCommand.csproj" />
|
||||
<ProjectReference Include="..\DeviceEditModule\DeviceEditModule.csproj" />
|
||||
<ProjectReference Include="..\ExportModule\ExportModule.csproj" />
|
||||
<ProjectReference Include="..\LoginModule\LoginModule.csproj" />
|
||||
<ProjectReference Include="..\MainModule\MainModule.csproj" />
|
||||
<ProjectReference Include="..\MonitorModule\MonitorModule.csproj" />
|
||||
|
||||
@@ -12,12 +12,12 @@ using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading; // 💡 新增:引入定时器命名空间
|
||||
using System.Windows.Threading;
|
||||
using UIShare;
|
||||
using UIShare.GlobalVariable;
|
||||
using UIShare.PubEvent;
|
||||
using UIShare.UIViewModel;
|
||||
using ZLGUSBCANFD;
|
||||
using SqlSugar;
|
||||
|
||||
namespace ADP.ViewModels
|
||||
{
|
||||
@@ -845,6 +845,10 @@ namespace ADP.ViewModels
|
||||
_regionManager.RequestNavigate("ShellViewManager", "BenchMovementView");
|
||||
break;
|
||||
case "曲线回读界面":
|
||||
if (_globalInfo.CurrentScope != "default") return;
|
||||
_regionManager.RequestNavigate("ShellViewManager", "CurveRecallView");
|
||||
break;
|
||||
case "测试报告导出界面":
|
||||
if (_globalInfo.CurrentScope != "default") return;
|
||||
_regionManager.RequestNavigate("ShellViewManager", "CurveRecallView");
|
||||
break;
|
||||
|
||||
@@ -71,6 +71,11 @@
|
||||
CommandParameter="{Binding Content, RelativeSource={RelativeSource Self}}"
|
||||
Style="{StaticResource MaterialDesignFlatButton}"
|
||||
Margin="8" />
|
||||
<Button Content="测试报告导出界面"
|
||||
Command="{Binding NavigateCommand}"
|
||||
CommandParameter="{Binding Content, RelativeSource={RelativeSource Self}}"
|
||||
Style="{StaticResource MaterialDesignFlatButton}"
|
||||
Margin="8" />
|
||||
</StackPanel>
|
||||
</materialDesign:DrawerHost.LeftDrawerContent>
|
||||
<Grid>
|
||||
@@ -189,6 +194,7 @@ Command="{Binding SelectCANMessageCommand}">
|
||||
Foreground="Black" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
|
||||
<!-- 获得文件路径字符串 -->
|
||||
<MenuItem Header="获得文件路径字符串"
|
||||
Foreground="Black"
|
||||
|
||||
20
ExportModule/ExportModule.cs
Normal file
20
ExportModule/ExportModule.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
using ExportModule.Views;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ExportModule
|
||||
{
|
||||
public class ExportModule: IModule
|
||||
{
|
||||
public void OnInitialized(IContainerProvider containerProvider)
|
||||
{
|
||||
IRegionManager regionManager = containerProvider.Resolve<IRegionManager>();
|
||||
}
|
||||
|
||||
public void RegisterTypes(IContainerRegistry containerRegistry)
|
||||
{
|
||||
containerRegistry.RegisterForNavigation<ExportView>("ExportView");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
16
ExportModule/ExportModule.csproj
Normal file
16
ExportModule/ExportModule.csproj
Normal file
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWPF>true</UseWPF>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ORM\ORM.csproj" />
|
||||
<ProjectReference Include="..\Service\Service.csproj" />
|
||||
<ProjectReference Include="..\UIShare\UIShare.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
68
ExportModule/ViewModels/ExportViewModel.cs
Normal file
68
ExportModule/ViewModels/ExportViewModel.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using Logger;
|
||||
using MahApps.Metro.Controls;
|
||||
using Model.Entity;
|
||||
using Model.Models;
|
||||
using NLog.Targets;
|
||||
using OxyPlot;
|
||||
using Service.Interface;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Threading;
|
||||
using UIShare.GlobalVariable;
|
||||
using UIShare.UIViewModel;
|
||||
using UIShare.ViewModelBase;
|
||||
|
||||
namespace ExportModule.ViewModels
|
||||
{
|
||||
public class ExportViewModel : NavigateViewModelBase, IRegionMemberLifetime, IDisposable
|
||||
{
|
||||
#region 属性
|
||||
public bool KeepAlive => true;
|
||||
#endregion
|
||||
|
||||
#region 命令
|
||||
|
||||
#endregion
|
||||
|
||||
#region 私有字段
|
||||
|
||||
#endregion
|
||||
public ExportViewModel(IContainerProvider containerProvider) : base(containerProvider)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#region 命令处理
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region 辅助方法
|
||||
|
||||
|
||||
#endregion
|
||||
#region 生命周期
|
||||
|
||||
public override void OnNavigatedTo(NavigationContext navigationContext)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
14
ExportModule/Views/ExportView.xaml
Normal file
14
ExportModule/Views/ExportView.xaml
Normal file
@@ -0,0 +1,14 @@
|
||||
<UserControl x:Class="ExportModule.Views.ExportView"
|
||||
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"
|
||||
xmlns:prism="http://prismlibrary.com/"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||
d:DesignHeight="1080" d:DesignWidth="1920">
|
||||
<Grid>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
28
ExportModule/Views/ExportView.xaml.cs
Normal file
28
ExportModule/Views/ExportView.xaml.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace ExportModule.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// ExportView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ExportView : UserControl
|
||||
{
|
||||
public ExportView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
64
Model/Entity/TestReportEntity.cs
Normal file
64
Model/Entity/TestReportEntity.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using SqlSugar;
|
||||
using System;
|
||||
|
||||
namespace Model.Entity
|
||||
{
|
||||
/// <summary>
|
||||
/// 测试报告记录:每次 ExecuteSteps / ExecuteErrorSteps 中每个步骤的执行结果。
|
||||
/// 同一次运行的所有步骤共享同一个 TestRoundId。
|
||||
/// </summary>
|
||||
public class TestReportEntity : BaseEntity
|
||||
{
|
||||
/// <summary>同一次运行的统一标识(StepRunning.TestRoundID)</summary>
|
||||
[SugarColumn(ColumnName = "TestRoundId", ColumnDescription = "运行轮次标识")]
|
||||
public Guid TestRoundId { get; set; }
|
||||
|
||||
/// <summary>作用域/台架名称</summary>
|
||||
[SugarColumn(ColumnName = "Scope", ColumnDescription = "台架名称")]
|
||||
public string Scope { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>步骤序号</summary>
|
||||
[SugarColumn(ColumnName = "StepIndex")]
|
||||
public int StepIndex { get; set; }
|
||||
|
||||
/// <summary>步骤名称</summary>
|
||||
[SugarColumn(ColumnName = "StepName", Length = 200)]
|
||||
public string StepName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>步骤类型(普通步骤/循环开始/循环结束)</summary>
|
||||
[SugarColumn(ColumnName = "StepType", Length = 50)]
|
||||
public string StepType { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>执行的方法名称</summary>
|
||||
[SugarColumn(ColumnName = "MethodName", Length = 200, IsNullable = true)]
|
||||
public string? MethodName { get; set; }
|
||||
|
||||
/// <summary>方法的完整类型名(实际方法所属类)</summary>
|
||||
[SugarColumn(ColumnName = "MethodFullName", Length = 500, IsNullable = true)]
|
||||
public string? MethodFullName { get; set; }
|
||||
|
||||
/// <summary>执行结果(成功/失败/未执行/跳过)</summary>
|
||||
[SugarColumn(ColumnName = "Result", Length = 20)]
|
||||
public string Result { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>执行耗时(毫秒)</summary>
|
||||
[SugarColumn(ColumnName = "RunTimeMs", IsNullable = true)]
|
||||
public int? RunTimeMs { get; set; }
|
||||
|
||||
/// <summary>输出值(如果有)</summary>
|
||||
[SugarColumn(ColumnName = "OutputValue", Length = 500, IsNullable = true)]
|
||||
public string? OutputValue { get; set; }
|
||||
|
||||
/// <summary>子程序嵌套深度(0=主程序)</summary>
|
||||
[SugarColumn(ColumnName = "Depth")]
|
||||
public int Depth { get; set; }
|
||||
|
||||
/// <summary>是否异常流程步骤</summary>
|
||||
[SugarColumn(ColumnName = "IsErrorStep")]
|
||||
public bool IsErrorStep { get; set; }
|
||||
|
||||
/// <summary>循环剩余次数(仅循环步骤有值)</summary>
|
||||
[SugarColumn(ColumnName = "LoopRemaining", IsNullable = true)]
|
||||
public int? LoopRemaining { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -101,6 +101,7 @@ namespace TestingModule.ViewModels
|
||||
_ScopedContext = scopedContext;
|
||||
_systemConfig = systemConfig;
|
||||
_globalInfo = globalInfo;
|
||||
Title = _systemConfig.Title;
|
||||
EditStepCommand = new DelegateCommand(EditStep);
|
||||
CopyStepCommand = new DelegateCommand(CopyStep);
|
||||
PasteStepCommand = new DelegateCommand(PasteStep);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
d:DesignWidth="800"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<GroupBox Header="程序编辑区域">
|
||||
<GroupBox Header="{Binding Title}">
|
||||
<TabControl SelectedIndex="{Binding SelectedTabIndex, Mode=TwoWay}">
|
||||
<i:Interaction.Behaviors>
|
||||
<behaviors:TabControlSelectionChangedBehavior Command="{Binding TabSelectionChangedCommand}"
|
||||
|
||||
@@ -3,6 +3,8 @@ using UIShare.PubEvent;
|
||||
using Common.Tools;
|
||||
using Logger;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using Model.Entity;
|
||||
using ORM;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
@@ -42,7 +44,7 @@ namespace UIShare
|
||||
/// <summary>标记是否已被注销,执行方法据此安全退出</summary>
|
||||
private volatile bool _disposed = false;
|
||||
|
||||
private Guid TestRoundID;
|
||||
public Guid TestRoundID;
|
||||
public StepRunning(ScopedContext ScopedContext, SystemConfig systemConfig,IEventAggregator eventAggregator, DeviceManager deviceManager)
|
||||
{
|
||||
_scopedContext = ScopedContext;
|
||||
@@ -114,6 +116,7 @@ namespace UIShare
|
||||
step.CurrentLoopCount = context.LoopCount;
|
||||
LoggerHelper.InfoWithNotify(_systemConfig.Title, $"循环开始,共{context.LoopCount}次", depth);
|
||||
index++;
|
||||
SaveStepRecord(step, depth, true);
|
||||
}
|
||||
|
||||
// 处理循环结束
|
||||
@@ -124,6 +127,7 @@ namespace UIShare
|
||||
LoggerHelper.ErrorWithNotify(_systemConfig.Title, "未匹配的循环结束指令", depth: depth);
|
||||
step.Result = 2;
|
||||
index++;
|
||||
SaveStepRecord(step, depth, true);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -138,6 +142,7 @@ namespace UIShare
|
||||
// 继续循环:跳转到循环开始后的第一条指令
|
||||
index = context.StartIndex + 1;
|
||||
LoggerHelper.InfoWithNotify(_systemConfig.Title, $"循环第{context.CurrentLoop}次结束,跳回开始,剩余{context.LoopCount - context.CurrentLoop}次", depth);
|
||||
SaveStepRecord(step, depth, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -154,6 +159,7 @@ namespace UIShare
|
||||
program.ErrorStepCollection.First(x => x.ID == step.LoopStartStepId).Result = 1;
|
||||
loopStopwatchStack.Pop();
|
||||
}
|
||||
SaveStepRecord(step, depth, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,6 +218,7 @@ namespace UIShare
|
||||
stepStopwatch.Stop();
|
||||
step.RunTime = (int)stepStopwatch.ElapsedMilliseconds;
|
||||
}
|
||||
SaveStepRecord(step, depth, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,6 +291,7 @@ namespace UIShare
|
||||
step.CurrentLoopCount = context.LoopCount;
|
||||
LoggerHelper.InfoWithNotify(_systemConfig.Title, $"循环开始({step.Name}),共{context.LoopCount}次", depth);
|
||||
index++;
|
||||
SaveStepRecord(step, depth, false);
|
||||
}
|
||||
|
||||
// 处理循环结束
|
||||
@@ -294,6 +302,7 @@ namespace UIShare
|
||||
LoggerHelper.ErrorWithNotify(_systemConfig.Title, "未匹配的循环结束指令", depth:depth);
|
||||
step.Result = 2;
|
||||
index++;
|
||||
SaveStepRecord(step, depth, false);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -308,6 +317,7 @@ namespace UIShare
|
||||
// 继续循环:跳转到循环开始后的第一条指令
|
||||
index = context.StartIndex + 1;
|
||||
LoggerHelper.InfoWithNotify(_systemConfig.Title, $"循环第{context.CurrentLoop}次结束,跳回开始,剩余{context.LoopCount - context.CurrentLoop}次", depth);
|
||||
SaveStepRecord(step, depth, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -324,6 +334,7 @@ namespace UIShare
|
||||
program.StepCollection.First(x => x.ID == step.LoopStartStepId).Result = 1;
|
||||
loopStopwatchStack.Pop();
|
||||
}
|
||||
SaveStepRecord(step, depth, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,6 +400,7 @@ namespace UIShare
|
||||
_scopedContext.SingleStep = false;
|
||||
_eventAggregator.GetEvent<RunSingalCompletedEvent>().Publish("Play");
|
||||
}
|
||||
SaveStepRecord(step, depth, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -669,6 +681,56 @@ namespace UIShare
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将单个步骤的执行结果保存到数据库(测试报告)。
|
||||
/// 同一次运行的所有步骤共享 TestRoundID,导出时按此 Guid 查询。
|
||||
/// </summary>
|
||||
private void SaveStepRecord(StepVM step, int depth, bool isErrorStep)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 获取输出参数值
|
||||
string? outputValue = null;
|
||||
if (step.Method != null)
|
||||
{
|
||||
var outputParam = step.Method.Parameters.FirstOrDefault(p => p.Category == ParameterCategory.Output);
|
||||
if (outputParam?.Value != null)
|
||||
outputValue = outputParam.Value.ToString();
|
||||
}
|
||||
|
||||
var entity = new TestReportEntity
|
||||
{
|
||||
TestRoundId = TestRoundID,
|
||||
Scope = _systemConfig.Title,
|
||||
StepIndex = step.Index,
|
||||
StepName = step.Name ?? "",
|
||||
StepType = step.StepType ?? "普通步骤",
|
||||
MethodName = step.Method?.Name,
|
||||
MethodFullName = step.Method?.FullName,
|
||||
Result = step.Result switch
|
||||
{
|
||||
-1 => "未执行",
|
||||
0 => "执行中",
|
||||
1 => "成功",
|
||||
2 => "失败",
|
||||
_ => "未知"
|
||||
},
|
||||
RunTimeMs = step.RunTime,
|
||||
OutputValue = outputValue,
|
||||
Depth = depth,
|
||||
IsErrorStep = isErrorStep,
|
||||
LoopRemaining = step.CurrentLoopCount,
|
||||
CreateTime = DateTime.Now
|
||||
};
|
||||
|
||||
SqlSugarContext.DbContext.Insertable(entity).ExecuteCommand();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.Error($"保存步骤记录失败 [{step.Index}]: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetAllStepStatus(ObservableCollection<StepVM> StepCollection)
|
||||
{
|
||||
foreach (var step in StepCollection)
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<ProjectReference Include="..\Common\Common.csproj" />
|
||||
<ProjectReference Include="..\DeviceCommand\DeviceCommand.csproj" />
|
||||
<ProjectReference Include="..\Logger\Logger.csproj" />
|
||||
<ProjectReference Include="..\ORM\ORM.csproj" />
|
||||
<ProjectReference Include="..\ZLGUSBCANFD\ZLGUSBCANFD.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user