桌面端密炼计划、胶料快检调整

This commit is contained in:
2026-06-18 15:18:11 +08:00
parent 372dc10be2
commit c54d54b40f
20 changed files with 1509 additions and 311 deletions

View File

@@ -2,12 +2,8 @@ using YY.Admin.Core.Entity;
namespace YY.Admin.Core.Services;
/// <summary>胶料快检记录操作台:密炼计划筛选、实验标准匹配、记录保存</summary>
/// <summary>胶料快检记录操作台:保存至 MES</summary>
public interface IRubberQuickTestOperationService
{
Task<List<MesXslMixingProductionPlan>> GetMixingProductionPlansAsync(CancellationToken ct = default);
Task<MesXslRubberQuickTestStd?> GetStdByRubberMaterialNameAsync(string rubberMaterialName, CancellationToken ct = default);
Task<string?> SaveRecordAsync(MesXslRubberQuickTestRecord record, CancellationToken ct = default);
}

View File

@@ -14,6 +14,13 @@ public interface IRubberQuickTestStdService
Task<MesXslRubberQuickTestStd?> GetByIdAsync(string id, CancellationToken ct = default);
Task<List<MesXslRubberQuickTestStd>> GetAllCachedAsync(CancellationToken ct = default);
Task<MesXslRubberQuickTestStd?> GetCachedByIdAsync(string id, CancellationToken ct = default);
/// <summary>优先读本地缓存;无明细时联网拉取详情并回写缓存</summary>
Task<MesXslRubberQuickTestStd?> GetWithLinesAsync(string id, CancellationToken ct = default);
/// <returns>本地缓存是否有变更(有差异才写入)</returns>
Task<bool> SyncFromRemoteAsync(CancellationToken ct = default);
}

View File

@@ -47,4 +47,18 @@ public class MesXslMixingProductionPlan
};
public string PlanDateText => PlanDate?.ToString("yyyy-MM-dd") ?? string.Empty;
/// <summary>计划+胶料号计划号_胶料名称如 SA0001_HB10001</summary>
public string PlanMaterialNo
{
get
{
var planNo = PlanNo?.Trim();
var materialName = MaterialName?.Trim();
if (string.IsNullOrEmpty(planNo) && string.IsNullOrEmpty(materialName)) return string.Empty;
if (string.IsNullOrEmpty(planNo)) return materialName ?? string.Empty;
if (string.IsNullOrEmpty(materialName)) return planNo;
return $"{planNo}_{materialName}";
}
}
}

View File

@@ -9,6 +9,9 @@ public class MesXslRubberQuickTestStd
public string? StdName { get; set; }
public string? TestMethodId { get; set; }
public string? TestMethodName { get; set; }
/// <summary>实验类型来自实验方法MES 回填)</summary>
public string? QuickTestTypeId { get; set; }
public string? QuickTestTypeName { get; set; }
public string? MixerType { get; set; }
public string? RubberMaterialId { get; set; }
public string? RubberMaterialName { get; set; }

View File

@@ -48,12 +48,12 @@ public class SysMenuSeedData : ISqlSugarEntitySeedData<SysMenu>
new SysMenu{ Id=1300150011001, Pid=1300150000101, Title="库区管理", Path="/xslmes/mesXslWarehouseArea", Name="mesXslWarehouseArea", Component="WarehouseAreaListView", Icon="&#xe7ce;", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=109 },
// 密炼物料皮重策略
new SysMenu{ Id=1300150011101, Pid=1300150000101, Title="密炼物料皮重策略", Path="/xslmes/mesXslMixerMaterialTareStrategy", Name="mesXslMixerMaterialTareStrategy", Component="MixerMaterialTareStrategyListView", Icon="&#xe7ce;", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
// 快检记录
new SysMenu{ Id=1300150011201, Pid=1300150000101, Title="快检记录", Path="/xslmes/rubberQuickTestOperation", Name="rubberQuickTestOperation", Component="RubberQuickTestOperationView", Icon="&#xe7de;", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=111 },
// 胶料快检实验标准(桌面端只读)
new SysMenu{ Id=1300150011301, Pid=1300150000101, Title="胶料快检实验标准", Path="/xslmes/mesXslRubberQuickTestStd", Name="mesXslRubberQuickTestStd", Component="RubberQuickTestStdListView", Icon="&#xe7ce;", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=112 },
// 胶料快检记录(紧接实验标准之后)
new SysMenu{ Id=1300150011201, Pid=1300150000101, Title="胶料快检记录", Path="/xslmes/rubberQuickTestOperation", Name="rubberQuickTestOperation", Component="RubberQuickTestOperationView", Icon="&#xe7de;", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=113 },
// 密炼计划
new SysMenu{ Id=1300150011401, Pid=1300150000101, Title="密炼计划", Path="/xslmes/mesXslMixingProductionPlan", Name="mesXslMixingProductionPlan", Component="MixingProductionPlanListView", Icon="&#xe7ce;", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=113 },
new SysMenu{ Id=1300150011401, Pid=1300150000101, Title="密炼计划", Path="/xslmes/mesXslMixingProductionPlan", Name="mesXslMixingProductionPlan", Component="MixingProductionPlanListView", Icon="&#xe7ce;", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=114 },
#endregion

View File

@@ -270,6 +270,8 @@ namespace YY.Admin.Core.SqlSugar
EnsureBaselineSysMenuSeed(db, config);
// 旧库升级:按种子补全缺失菜单及租户/角色授权(仅插入缺失项)
EnsureIncrementalDesktopMenuSeed(db, config);
// 旧库升级:胶料快检记录菜单名称与排序
EnsureRubberQuickTestRecordMenuPatch(db, config);
}
/// <summary>
@@ -494,6 +496,43 @@ namespace YY.Admin.Core.SqlSugar
}
}
/// <summary>
/// 旧库升级:胶料快检记录改名为「胶料快检记录」,排序置于胶料快检实验标准之后。
/// </summary>
private static void EnsureRubberQuickTestRecordMenuPatch(SqlSugarScope db, DbConnectionConfig config)
{
try
{
if (!string.Equals(config.ConfigId.ToString(), SqlSugarConst.MainConfigId, StringComparison.Ordinal))
return;
if (config.DbType != DbType.Sqlite)
return;
var dbProvider = db.GetConnectionScope(config.ConfigId);
var menuEntityInfo = dbProvider.EntityMaintenance.GetEntityInfo(typeof(SysMenu));
if (!dbProvider.DbMaintenance.IsAnyTable(menuEntityInfo.DbTableName, false))
return;
const long quickTestRecordMenuId = 1300150011201;
const long mixingPlanMenuId = 1300150011401;
dbProvider.Updateable<SysMenu>()
.SetColumns(m => m.Title == "胶料快检记录")
.SetColumns(m => m.OrderNo == 113)
.Where(m => m.Id == quickTestRecordMenuId)
.ExecuteCommand();
dbProvider.Updateable<SysMenu>()
.SetColumns(m => m.OrderNo == 114)
.Where(m => m.Id == mixingPlanMenuId)
.ExecuteCommand();
}
catch
{
// 启动阶段不因菜单补丁失败而阻断
}
}
/// <summary>
/// 兼容旧库:补齐桌面端「登录设置」所需的 sys_config 配置项(升级前库可能缺少这些 code
/// </summary>

View File

@@ -14,7 +14,6 @@ public class RubberQuickTestOperationService : IRubberQuickTestOperationService,
private readonly IHttpClientFactory _httpClientFactory;
private readonly IConfiguration _configuration;
private readonly INetworkMonitor _networkMonitor;
private readonly IMixingProductionPlanService _mixingProductionPlanService;
private readonly ILoggerService _logger;
private static readonly JsonSerializerOptions _jsonOpts = new()
@@ -28,54 +27,20 @@ public class RubberQuickTestOperationService : IRubberQuickTestOperationService,
IHttpClientFactory httpClientFactory,
IConfiguration configuration,
INetworkMonitor networkMonitor,
IMixingProductionPlanService mixingProductionPlanService,
ILoggerService logger)
{
_httpClientFactory = httpClientFactory;
_configuration = configuration;
_networkMonitor = networkMonitor;
_mixingProductionPlanService = mixingProductionPlanService;
_logger = logger;
}
private string BaseUrl => (_configuration.GetValue<string>("JeecgIntegration:BaseUrl") ?? "http://localhost:8080/jeecg-boot").TrimEnd('/');
private int DefaultTenantId => (int?)_configuration.GetValue<long?>("JeecgIntegration:DefaultTenantId") ?? 1002;
public async Task<List<MesXslMixingProductionPlan>> GetMixingProductionPlansAsync(CancellationToken ct = default)
{
var result = await _mixingProductionPlanService.GetAllCachedAsync(ct).ConfigureAwait(false);
_logger.Information($"[快检记录] 加载密炼生产计划 {result.Count} 条");
return result;
}
public async Task<MesXslRubberQuickTestStd?> GetStdByRubberMaterialNameAsync(string rubberMaterialName, CancellationToken ct = default)
{
if (string.IsNullOrWhiteSpace(rubberMaterialName))
return null;
if (!_networkMonitor.IsOnline)
throw new InvalidOperationException("网络未连接,无法加载实验标准");
var encoded = Uri.EscapeDataString(rubberMaterialName.Trim());
var url = $"{BaseUrl}/xslmes/mesXslRubberQuickTestStd/anon/queryByRubberMaterialName?rubberMaterialName={encoded}";
using var client = _httpClientFactory.CreateClient("JeecgApi");
var resp = await client.GetAsync(url, ct).ConfigureAwait(false);
var json = await resp.Content.ReadAsStringAsync(ct).ConfigureAwait(false);
using var doc = JsonDocument.Parse(json);
if (!doc.RootElement.TryGetProperty("success", out var successEl) || !successEl.GetBoolean())
{
var msg = doc.RootElement.TryGetProperty("message", out var msgEl) ? msgEl.GetString() : "查询实验标准失败";
_logger.Warning($"[快检记录] 实验标准查询失败: {msg}");
return null;
}
if (!doc.RootElement.TryGetProperty("result", out var resultEl) || resultEl.ValueKind == JsonValueKind.Null)
return null;
return resultEl.Deserialize<MesXslRubberQuickTestStd>(_jsonOpts);
}
public async Task<string?> SaveRecordAsync(MesXslRubberQuickTestRecord record, CancellationToken ct = default)
{
if (!_networkMonitor.IsOnline)
throw new InvalidOperationException("网络未连接,无法保存快检记录");
throw new InvalidOperationException("网络未连接,无法保存胶料快检记录");
var url = $"{BaseUrl}/xslmes/mesXslRubberQuickTestRecord/anon/add";
using var client = _httpClientFactory.CreateClient("JeecgApi");
@@ -89,7 +54,19 @@ public class RubberQuickTestOperationService : IRubberQuickTestOperationService,
var msg = doc.RootElement.TryGetProperty("message", out var msgEl) ? msgEl.GetString() : "保存失败";
throw new InvalidOperationException(msg ?? "保存失败");
}
_logger.Information($"[快检记录] 保存成功 recordNo={record.RecordNo}");
return doc.RootElement.TryGetProperty("message", out var m) ? m.GetString() : "保存成功";
string? recordNo = null;
if (doc.RootElement.TryGetProperty("result", out var resultEl))
{
if (resultEl.ValueKind == JsonValueKind.String)
recordNo = resultEl.GetString();
else if (resultEl.ValueKind == JsonValueKind.Object
&& resultEl.TryGetProperty("recordNo", out var noEl))
recordNo = noEl.GetString();
}
recordNo ??= record.RecordNo;
record.RecordNo = recordNo;
_logger.Information($"[胶料快检记录] 保存成功 recordNo={recordNo}");
return recordNo;
}
}

View File

@@ -135,6 +135,42 @@ public class RubberQuickTestStdService : IRubberQuickTestStdService, ISingletonD
}
}
public Task<List<MesXslRubberQuickTestStd>> GetAllCachedAsync(CancellationToken ct = default)
{
ct.ThrowIfCancellationRequested();
lock (_cacheLock)
return Task.FromResult(_localCache.Select(CloneMain).ToList());
}
public Task<MesXslRubberQuickTestStd?> GetCachedByIdAsync(string id, CancellationToken ct = default)
{
ct.ThrowIfCancellationRequested();
if (string.IsNullOrWhiteSpace(id)) return Task.FromResult<MesXslRubberQuickTestStd?>(null);
lock (_cacheLock)
{
var found = _localCache.FirstOrDefault(x => string.Equals(x.Id, id, StringComparison.OrdinalIgnoreCase));
return Task.FromResult(found != null ? CloneMain(found) : null);
}
}
public async Task<MesXslRubberQuickTestStd?> GetWithLinesAsync(string id, CancellationToken ct = default)
{
if (string.IsNullOrWhiteSpace(id)) return null;
var cached = await GetCachedByIdAsync(id, ct).ConfigureAwait(false);
if (cached?.LineList is { Count: > 0 })
return cached;
if (_networkMonitor.IsOnline)
{
var detail = await GetByIdAsync(id, ct).ConfigureAwait(false);
if (detail != null)
return detail;
}
return cached;
}
public async Task<bool> SyncFromRemoteAsync(CancellationToken ct = default)
{
await _syncLock.WaitAsync(ct).ConfigureAwait(false);
@@ -309,6 +345,8 @@ public class RubberQuickTestStdService : IRubberQuickTestStdService, ISingletonD
StdName = x.StdName,
TestMethodId = x.TestMethodId,
TestMethodName = x.TestMethodName,
QuickTestTypeId = x.QuickTestTypeId,
QuickTestTypeName = x.QuickTestTypeName,
MixerType = x.MixerType,
RubberMaterialId = x.RubberMaterialId,
RubberMaterialName = x.RubberMaterialName,

View File

@@ -98,7 +98,7 @@ namespace YY.Admin
containerRegistry.RegisterForNavigation<WarehouseAreaListView>();
// 密炼物料皮重策略
containerRegistry.RegisterForNavigation<MixerMaterialTareStrategyListView>();
// 快检记录操作台
// 胶料快检记录操作台
containerRegistry.RegisterForNavigation<RubberQuickTestOperationView>();
// 胶料快检实验标准(只读)
containerRegistry.RegisterForNavigation<RubberQuickTestStdListView>();

View File

@@ -152,7 +152,7 @@ namespace YY.Admin.ViewModels.Control
["/xslmes/mesXslMixerMaterialTareStrategy"] = "MixerMaterialTareStrategyListView",
["mesXslMixerMaterialTareStrategy"] = "MixerMaterialTareStrategyListView",
// 已实现页面:快检记录操作台
// 已实现页面:胶料快检记录操作台
["RubberQuickTestOperationView"] = "RubberQuickTestOperationView",
["/xslmes/rubberQuickTestOperation"] = "RubberQuickTestOperationView",
["rubberQuickTestOperation"] = "RubberQuickTestOperationView",

View File

@@ -112,12 +112,14 @@
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<DataGrid.Columns>
<DataGridTextColumn Header="密炼日期" Binding="{Binding PlanDateText}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="110"/>
<DataGridTextColumn Header="机台名称" Binding="{Binding MachineName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="140"/>
<DataGridTextColumn Header="班次" Binding="{Binding ShiftFlagText}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="80"/>
<DataGridTextColumn Header="计划号" Binding="{Binding PlanNo}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="140"/>
<DataGridTextColumn Header="计划数量" Binding="{Binding PlanCount}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="90"/>
<DataGridTextColumn Header="胶料名称" Binding="{Binding MaterialName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="*"/>
<!-- 固定列宽合计约 920px宽屏右侧留白 -->
<DataGridTextColumn Header="密炼日期" Binding="{Binding PlanDateText}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="100"/>
<DataGridTextColumn Header="机台名称" Binding="{Binding MachineName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
<DataGridTextColumn Header="班次" Binding="{Binding ShiftFlagText}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="68"/>
<DataGridTextColumn Header="计划" Binding="{Binding PlanNo}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="160"/>
<DataGridTextColumn Header="胶料名称" Binding="{Binding MaterialName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
<DataGridTextColumn Header="计划+胶料号" Binding="{Binding PlanMaterialNo}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="240"/>
<DataGridTextColumn Header="计划数量" Binding="{Binding PlanCount}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="76"/>
</DataGrid.Columns>
</DataGrid>

View File

@@ -28,7 +28,7 @@
<Grid Margin="12">
<Grid.RowDefinitions>
<RowDefinition Height="64"/>
<RowDefinition Height="80"/>
<RowDefinition Height="*"/>
<RowDefinition Height="56"/>
</Grid.RowDefinitions>
@@ -40,19 +40,19 @@
<Border Width="40" Height="40" CornerRadius="8" Background="{DynamicResource PrimaryBrush}" Margin="0,0,12,0">
<md:PackIcon Kind="Flask" Width="22" Height="22" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<StackPanel>
<TextBlock Text="快检记录" FontSize="18" FontWeight="Bold"/>
<TextBlock Text="密炼快检试验操作台" FontSize="12" Foreground="{DynamicResource SecondaryTextBrush}"/>
<StackPanel VerticalAlignment="Center">
<TextBlock Text="无转子流变仪 MDR S3L" FontSize="24" FontWeight="Bold"/>
<TextBlock Text="胶料快检记录 · 密炼快检试验操作台" FontSize="12" Foreground="{DynamicResource SecondaryTextBrush}" Margin="0,4,0,0"/>
</StackPanel>
</StackPanel>
</Border>
<!-- 主体 2:1 -->
<!-- 主体 3:2 -->
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="12"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<!-- 左侧:曲线 + 试验结果 -->
@@ -62,7 +62,7 @@
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<Border Width="4" Height="18" CornerRadius="2" Background="#1890ff"/>
<TextBlock Text="温度(℃)曲线" Style="{StaticResource SectionTitleStyle}"/>
<TextBlock Text="温度(℃)曲线" Style="{StaticResource SectionTitleStyle}"/>
<Button Content="刷新演示" Command="{Binding RefreshChartDemoCommand}" Style="{StaticResource ButtonDefault}" Height="28" Padding="10,0" Margin="12,0,0,0"/>
</StackPanel>
<TextBlock Text="{Binding ChartDemoHint}" FontSize="11" Foreground="{DynamicResource SecondaryTextBrush}" Margin="0,0,0,6"/>
@@ -79,7 +79,7 @@
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<Border Width="4" Height="18" CornerRadius="2" Background="#1890ff"/>
<TextBlock Text="S'(dNm)曲线" Style="{StaticResource SectionTitleStyle}"/>
<TextBlock Text="S'(dNm)曲线" Style="{StaticResource SectionTitleStyle}"/>
</StackPanel>
<Border Height="200" CornerRadius="4">
<lvc:CartesianChart Series="{Binding TorqueSeries}"
@@ -157,11 +157,24 @@
<Border Width="4" Height="18" CornerRadius="2" Background="#1890ff"/>
<TextBlock Text="试验信息" Style="{StaticResource SectionTitleStyle}"/>
</StackPanel>
<Button Content="刷新计划" Command="{Binding RefreshPlansCommand}"
<Button Content="刷新本地数据" Command="{Binding RefreshPlansCommand}"
Style="{StaticResource ButtonDefault}" Height="26" Padding="8,0"
HorizontalAlignment="Right" VerticalAlignment="Center"/>
</Grid>
<hc:Row Gutter="10">
<!-- 快检记录号(保存后生成,单独一行) -->
<hc:Col Span="24">
<hc:TextBox Text="{Binding RecordNo, Mode=OneWay}"
IsReadOnly="True"
hc:InfoElement.Title="快检记录号"
hc:InfoElement.TitleWidth="90"
hc:InfoElement.TitlePlacement="Left"
hc:InfoElement.Placeholder="保存后自动生成"
Margin="0,0,0,8"/>
</hc:Col>
</hc:Row>
<hc:Row Gutter="10">
<!-- 密炼日期 -->
<hc:Col Span="12">
@@ -198,11 +211,11 @@
hc:InfoElement.Symbol="*"
Margin="0,0,0,8"/>
</hc:Col>
<!-- 密炼生产计划 -->
<!-- 密炼计划(计划+胶料号) -->
<hc:Col Span="24">
<hc:ComboBox ItemsSource="{Binding PlanOptions}"
SelectedItem="{Binding SelectedPlan}"
DisplayMemberPath="DisplayText"
DisplayMemberPath="PlanMaterialNo"
hc:InfoElement.Title="密炼计划"
hc:InfoElement.TitleWidth="90"
hc:InfoElement.TitlePlacement="Left"
@@ -211,18 +224,6 @@
hc:InfoElement.Symbol="*"
Margin="0,0,0,8"/>
</hc:Col>
<!-- 生产订单号 -->
<hc:Col Span="12">
<hc:TextBox Text="{Binding ProductionOrderNo, Mode=OneWay}"
IsReadOnly="True"
hc:InfoElement.Title="生产订单号"
hc:InfoElement.TitleWidth="90"
hc:InfoElement.TitlePlacement="Left"
hc:InfoElement.Placeholder="选择计划后自动带出"
hc:InfoElement.Necessary="True"
hc:InfoElement.Symbol="*"
Margin="0,0,0,8"/>
</hc:Col>
<!-- 胶料名称 -->
<hc:Col Span="12">
<hc:TextBox Text="{Binding RubberMaterialName, Mode=OneWay}"
@@ -233,6 +234,29 @@
hc:InfoElement.Placeholder="选择计划后自动带出"
Margin="0,0,0,8"/>
</hc:Col>
<!-- 实验标准 -->
<hc:Col Span="12">
<hc:ComboBox ItemsSource="{Binding StdOptions}"
SelectedItem="{Binding SelectedStd}"
DisplayMemberPath="StdName"
hc:InfoElement.Title="实验标准"
hc:InfoElement.TitleWidth="90"
hc:InfoElement.TitlePlacement="Left"
hc:InfoElement.Placeholder="按胶料名称筛选后选择"
hc:InfoElement.Necessary="True"
hc:InfoElement.Symbol="*"
Margin="0,0,0,8"/>
</hc:Col>
<!-- 实验方法 -->
<hc:Col Span="12">
<hc:TextBox Text="{Binding TestMethodName, Mode=OneWay}"
IsReadOnly="True"
hc:InfoElement.Title="实验方法"
hc:InfoElement.TitleWidth="90"
hc:InfoElement.TitlePlacement="Left"
hc:InfoElement.Placeholder="选择标准后自动带出"
Margin="0,0,0,8"/>
</hc:Col>
<!-- 车次 -->
<hc:Col Span="12">
<hc:TextBox Text="{Binding TrainNo, UpdateSourceTrigger=PropertyChanged}"
@@ -255,11 +279,31 @@
hc:InfoElement.Necessary="True"
hc:InfoElement.Symbol="*"
hc:InfoElement.ShowClearButton="True"
Margin="0,0,0,8"/>
</hc:Col>
<!-- 检验结果(由试验结果区域自动判定,只读) -->
<hc:Col Span="12">
<hc:TextBox Text="{Binding OverallInspectResultDisplay, Mode=OneWay}"
IsReadOnly="True"
hc:InfoElement.Title="检验结果"
hc:InfoElement.TitleWidth="90"
hc:InfoElement.TitlePlacement="Left"
hc:InfoElement.Placeholder="自动判定"
Margin="0,0,0,8"/>
</hc:Col>
<!-- 检验人(当前登录用户,只读) -->
<hc:Col Span="24">
<hc:TextBox Text="{Binding InspectorDisplay, Mode=OneWay}"
IsReadOnly="True"
hc:InfoElement.Title="检验人"
hc:InfoElement.TitleWidth="90"
hc:InfoElement.TitlePlacement="Left"
hc:InfoElement.Placeholder="当前登录用户"
Margin="0,0,0,0"/>
</hc:Col>
</hc:Row>
<TextBlock Text="按密炼日期 → 机台 → 班次筛选生产计划;胶料名称用于匹配快检实验标准"
<TextBlock Text="密炼计划、实验标准均来自桌面端本地缓存;按密炼日期筛选计划,再按胶料名称选择实验标准"
FontSize="11"
Foreground="{DynamicResource SecondaryTextBrush}"
Margin="0,8,0,0"
@@ -278,11 +322,24 @@
AutoGenerateColumns="False"
IsReadOnly="True"
HeadersVisibility="Column"
MaxHeight="240">
MaxHeight="240"
ColumnWidth="*">
<DataGrid.Columns>
<DataGridTextColumn Header="数据点" Binding="{Binding PointName}" Width="*"/>
<DataGridTextColumn Header="下限值" Binding="{Binding LowerLimit}" Width="70"/>
<DataGridTextColumn Header="上限值" Binding="{Binding UpperLimit}" Width="70"/>
<DataGridTextColumn Header="数据点" Binding="{Binding PointName}" Width="5*"/>
<DataGridTextColumn Header="下限值" Binding="{Binding LowerLimit}" Width="2.5*">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="上限值" Binding="{Binding UpperLimit}" Width="2.5*">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
@@ -294,7 +351,7 @@
<!-- 底部操作 -->
<Border Grid.Row="2" Background="{DynamicResource RegionBrush}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="0,1,0,0" Margin="-12,8,-12,-12">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="20,0">
<Button Content="保存快检记录" Command="{Binding SaveCommand}" Style="{StaticResource ButtonPrimary}" Height="36" Width="140"/>
<Button Content="保存胶料快检记录" Command="{Binding SaveCommand}" Style="{StaticResource ButtonPrimary}" Height="36" Width="160"/>
</StackPanel>
</Border>
</Grid>

View File

@@ -1,72 +1,118 @@
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using YY.Admin.ViewModels.RubberQuickTest;
namespace YY.Admin.Views.RubberQuickTest;
public partial class RubberQuickTestOperationView : UserControl
{
private RubberQuickTestOperationViewModel? _vm;
private RubberQuickTestOperationViewModel? _vm;
public RubberQuickTestOperationView()
{
InitializeComponent();
DataContextChanged += OnDataContextChanged;
}
private void OnDataContextChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e)
{
if (_vm != null)
_vm.InspectColumnsChanged -= RebuildInspectColumns;
_vm = DataContext as RubberQuickTestOperationViewModel;
if (_vm != null)
public RubberQuickTestOperationView()
{
_vm.InspectColumnsChanged += RebuildInspectColumns;
RebuildInspectColumns();
}
}
private void RebuildInspectColumns()
{
if (_vm == null) return;
InspectResultGrid.Columns.Clear();
InspectResultGrid.Columns.Add(new DataGridTextColumn
{
Header = "编号",
Binding = new System.Windows.Data.Binding("RowNo"),
IsReadOnly = true,
Width = 80
});
for (int i = 0; i < _vm.DataPointColumns.Count; i++)
{
var col = _vm.DataPointColumns[i];
var binding = new System.Windows.Data.Binding($"Cells[{i}].Value")
{
UpdateSourceTrigger = System.Windows.Data.UpdateSourceTrigger.PropertyChanged,
Mode = System.Windows.Data.BindingMode.TwoWay
};
InspectResultGrid.Columns.Add(new DataGridTextColumn
{
Header = col.PointName ?? $"点{i + 1}",
Binding = binding,
Width = 90,
IsReadOnly = false
});
InitializeComponent();
Loaded += OnLoaded;
DataContextChanged += OnDataContextChanged;
Unloaded += (_, _) => DetachViewModel();
}
InspectResultGrid.Columns.Add(new DataGridTextColumn
private void OnLoaded(object sender, RoutedEventArgs e)
{
Header = "实验结果",
Binding = new System.Windows.Data.Binding("InspectResultText"),
IsReadOnly = true,
Width = 90
});
}
// 兜底AutoWireViewModel 可能在构造函数订阅 DataContextChanged 之前就设置了 DataContext
AttachViewModel(DataContext as RubberQuickTestOperationViewModel);
}
private void InspectResultGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (_vm == null) return;
_vm.SelectedInspectRow = InspectResultGrid.SelectedItem as QuickTestInspectRowViewModel;
}
private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
DetachViewModel();
AttachViewModel(DataContext as RubberQuickTestOperationViewModel);
}
private void AttachViewModel(RubberQuickTestOperationViewModel? vm)
{
if (vm == null || ReferenceEquals(_vm, vm)) return;
_vm = vm;
_vm.InspectColumnsChanged += RebuildInspectColumns;
_vm.DataPointColumns.CollectionChanged += OnDataPointColumnsChanged;
RebuildInspectColumns();
}
private void DetachViewModel()
{
if (_vm == null) return;
_vm.InspectColumnsChanged -= RebuildInspectColumns;
_vm.DataPointColumns.CollectionChanged -= OnDataPointColumnsChanged;
_vm = null;
}
private void OnDataPointColumnsChanged(object? sender, NotifyCollectionChangedEventArgs e)
=> RebuildInspectColumns();
private void RebuildInspectColumns()
{
if (!Dispatcher.CheckAccess())
{
Dispatcher.Invoke(RebuildInspectColumns);
return;
}
var vm = _vm ?? DataContext as RubberQuickTestOperationViewModel;
if (vm == null) return;
InspectResultGrid.Columns.Clear();
InspectResultGrid.Columns.Add(new DataGridTextColumn
{
Header = "编号",
Binding = new Binding(nameof(QuickTestInspectRowViewModel.RowNo))
{
Mode = BindingMode.OneWay
},
IsReadOnly = true,
Width = 80
});
for (int i = 0; i < vm.DataPointColumns.Count; i++)
{
var col = vm.DataPointColumns[i];
var columnIndex = i;
var header = string.IsNullOrWhiteSpace(col.PointName)
? $"数据点{columnIndex + 1}"
: col.PointName;
InspectResultGrid.Columns.Add(new DataGridTextColumn
{
Header = header,
Binding = new Binding($"Cells[{columnIndex}].Value")
{
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
Mode = BindingMode.TwoWay,
TargetNullValue = string.Empty
},
Width = 100,
IsReadOnly = false
});
}
InspectResultGrid.Columns.Add(new DataGridTextColumn
{
Header = "实验结果",
Binding = new Binding(nameof(QuickTestInspectRowViewModel.InspectResultText))
{
Mode = BindingMode.OneWay
},
IsReadOnly = true,
Width = 90
});
}
private void InspectResultGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var vm = _vm ?? DataContext as RubberQuickTestOperationViewModel;
if (vm == null) return;
vm.SelectedInspectRow = InspectResultGrid.SelectedItem as QuickTestInspectRowViewModel;
}
}

View File

@@ -39,6 +39,11 @@
hc:InfoElement.Title="实验方法" hc:InfoElement.TitleWidth="90" hc:InfoElement.TitlePlacement="Left"
Margin="0,0,0,12"/>
</hc:Col>
<hc:Col Span="12">
<hc:TextBox Text="{Binding Std.QuickTestTypeName, Mode=OneWay}" IsReadOnly="True"
hc:InfoElement.Title="实验类型" hc:InfoElement.TitleWidth="90" hc:InfoElement.TitlePlacement="Left"
Margin="0,0,0,12"/>
</hc:Col>
<hc:Col Span="12">
<hc:TextBox Text="{Binding Std.RubberMaterialName, Mode=OneWay}" IsReadOnly="True"
hc:InfoElement.Title="胶料名称" hc:InfoElement.TitleWidth="90" hc:InfoElement.TitlePlacement="Left"

View File

@@ -88,9 +88,10 @@
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<DataGrid.Columns>
<DataGridTextColumn Header="实验标准名称" Binding="{Binding StdName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="180"/>
<DataGridTextColumn Header="实验方法" Binding="{Binding TestMethodName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="140"/>
<DataGridTextColumn Header="胶料名称" Binding="{Binding RubberMaterialName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="140"/>
<DataGridTextColumn Header="实验标准名称" Binding="{Binding StdName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="160"/>
<DataGridTextColumn Header="实验方法" Binding="{Binding TestMethodName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
<DataGridTextColumn Header="实验类型" Binding="{Binding QuickTestTypeName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="100"/>
<DataGridTextColumn Header="胶料名称" Binding="{Binding RubberMaterialName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
<DataGridTextColumn Header="发行编号" Binding="{Binding IssueNumber}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
<DataGridTextColumn Header="发行部门" Binding="{Binding IssueDeptName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
<DataGridTextColumn Header="启用状态" Binding="{Binding EnableStatusText}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="90"/>