This commit is contained in:
xyy
2026-04-12 16:46:55 +08:00
parent ea8e76bff4
commit e774c2374c
11 changed files with 303 additions and 47 deletions

33
Views/LoginWindow.xaml Normal file
View File

@@ -0,0 +1,33 @@
<Window x:Class="MembranePoreTester.Views.LoginWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="登录" Height="250" Width="350"
WindowStartupLocation="CenterScreen"
ResizeMode="NoResize">
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="膜孔径测试系统" FontSize="18" FontWeight="Bold" HorizontalAlignment="Center" Margin="0,0,0,20"/>
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,5">
<Label Width="80" Content="用户名:"/>
<!--<TextBox x:Name="txtUsername" Width="180" Text="admin"/>-->
<ComboBox x:Name="cmbRole" Width="180" SelectedIndex="0">
<ComboBoxItem Content="管理员" Tag="Admin"/>
<ComboBoxItem Content="操作员" Tag="Operator"/>
</ComboBox>
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Horizontal" Margin="0,5">
<Label Width="80" Content="密码:"/>
<PasswordBox x:Name="txtPassword" Width="180" PasswordChar="*"/>
</StackPanel>
<StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,20,0,0">
<Button x:Name="btnLogin" Content="登录" Width="80" Margin="10" Click="BtnLogin_Click"/>
<Button x:Name="btnChangePwd" Content="修改密码" Width="80" Margin="10" Click="BtnChangePwd_Click"/>
<Button x:Name="btnExit" Content="退出" Width="80" Margin="10" Click="BtnExit_Click"/>
</StackPanel>
</Grid>
</Window>

168
Views/LoginWindow.xaml.cs Normal file
View File

@@ -0,0 +1,168 @@
using System;
using System.IO;
using System.Text.Json;
using System.Windows;
using System.Windows.Controls;
using MembranePoreTester.Models;
namespace MembranePoreTester.Views
{
public partial class LoginWindow : Window
{
private const string PasswordFile = "passwords.json";
public LoginWindow()
{
InitializeComponent();
EnsurePasswordFile();
}
private void EnsurePasswordFile()
{
if (!File.Exists(PasswordFile))
{
var defaultPasswords = new
{
AdminPassword = "admin123",
OperatorPassword = "oper123"
};
string json = JsonSerializer.Serialize(defaultPasswords, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(PasswordFile, json);
}
}
private void BtnLogin_Click(object sender, RoutedEventArgs e)
{
string role = ((ComboBoxItem)cmbRole.SelectedItem).Tag.ToString();
string password = txtPassword.Password;
string expectedPassword = GetPassword(role);
if (password == expectedPassword)
{
App.CurrentUserRole = role == "Admin" ? UserRole.Admin : UserRole.Operator;
DialogResult = true;
Close();
}
else
{
MessageBox.Show("密码错误", "登录失败", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void BtnChangePwd_Click(object sender, RoutedEventArgs e)
{
string role = ((ComboBoxItem)cmbRole.SelectedItem).Tag.ToString();
string title = role == "Admin" ? "修改管理员密码" : "修改操作员密码";
var dialog = new Window
{
Title = title,
Width = 350,
Height = 250,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
Owner = this,
ResizeMode = ResizeMode.NoResize,
Content = new StackPanel
{
Margin = new Thickness(20),
Children =
{
new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0,10,0,10),
Children = { new Label { Width = 80, Content = "新密码:" }, new PasswordBox { Name = "newPwd", Width = 180 } } },
new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0,10,0,10),
Children = { new Label { Width = 80, Content = "确认密码:" }, new PasswordBox { Name = "confirmPwd", Width = 180 } } },
new StackPanel { Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Center, Margin = new Thickness(0,20,0,0),
Children = { new Button { Content = "确定", Width = 80, Margin = new Thickness {Left= 5} }, new Button { Content = "取消", Width = 80, Margin = new Thickness {Left= 5} } } }
}
}
};
var confirmBtn = ((StackPanel)((StackPanel)dialog.Content).Children[2]).Children[0] as Button;
var cancelBtn = ((StackPanel)((StackPanel)dialog.Content).Children[2]).Children[1] as Button;
var newPwdBox = ((StackPanel)((StackPanel)dialog.Content).Children[0]).Children[1] as PasswordBox;
var confirmPwdBox = ((StackPanel)((StackPanel)dialog.Content).Children[1]).Children[1] as PasswordBox;
confirmBtn.Click += (s, ev) =>
{
string newPwd = newPwdBox.Password;
string confirmPwd = confirmPwdBox.Password;
if (string.IsNullOrEmpty(newPwd))
{
MessageBox.Show("密码不能为空", "错误", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if (newPwd != confirmPwd)
{
MessageBox.Show("两次输入的密码不一致", "错误", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if (UpdatePassword(role, newPwd))
{
MessageBox.Show("密码修改成功,下次登录生效", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
dialog.Close();
}
else
{
MessageBox.Show("密码修改失败,请检查文件权限", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
};
cancelBtn.Click += (s, ev) => dialog.Close();
dialog.ShowDialog();
}
private void BtnExit_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
Close();
}
private string GetPassword(string role)
{
if (!File.Exists(PasswordFile)) return role == "Admin" ? "admin123" : "oper123";
try
{
string json = File.ReadAllText(PasswordFile);
using JsonDocument doc = JsonDocument.Parse(json);
string key = role == "Admin" ? "AdminPassword" : "OperatorPassword";
if (doc.RootElement.TryGetProperty(key, out JsonElement value))
return value.GetString();
return role == "Admin" ? "admin123" : "oper123";
}
catch
{
return role == "Admin" ? "admin123" : "oper123";
}
}
private bool UpdatePassword(string role, string newPassword)
{
try
{
Dictionary<string, string> passwords;
if (File.Exists(PasswordFile))
{
string json = File.ReadAllText(PasswordFile);
passwords = JsonSerializer.Deserialize<Dictionary<string, string>>(json);
}
else
{
passwords = new Dictionary<string, string>();
}
string key = role == "Admin" ? "AdminPassword" : "OperatorPassword";
passwords[key] = newPassword;
string newJson = JsonSerializer.Serialize(passwords, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(PasswordFile, newJson);
return true;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"修改密码失败: {ex.Message}");
return false;
}
}
}
}

View File

@@ -116,7 +116,7 @@
<Border DockPanel.Dock="Top" Background="White" BorderBrush="#E9ECF0" BorderThickness="0,0,0,1" Padding="10,5">
<StackPanel Orientation="Horizontal">
<Button Content="📋 历史记录" Click="OpenHistory_Click" Width="100" HorizontalAlignment="Left" Background="#607D8B"/>
<Button Content="阀门控制" Click="OpenValveControl_Click" Padding="10,5" Margin="5"/>
<Button x:Name="btnValveControl" Content="阀门控制" Click="OpenValveControl_Click" Padding="10,5" Margin="5"/>
</StackPanel>
</Border>

View File

@@ -12,6 +12,19 @@ namespace MembranePoreTester.Views
{
InitializeComponent();
HistoryWindow.LoadRecordEvent += OnLoadRecord;
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
// 根据角色设置权限
bool isAdmin = App.CurrentUserRole == Models.UserRole.Admin;
// 禁用/启用阀门控制按钮(假设 x:Name="btnValveControl"
if (btnValveControl != null) btnValveControl.IsEnabled = isAdmin;
//// 如果还有参数设置按钮(例如工具栏上的按钮)
//if (btnParameterSetting != null) btnParameterSetting.IsEnabled = isAdmin;
//// 其他需要限制的全局控件可在此添加
}
private void OnLoadRecord(object sender, LoadRecordEventArgs e)
@@ -32,32 +45,34 @@ namespace MembranePoreTester.Views
}
}
private void OpenHistory_Click(object sender, RoutedEventArgs e)
{
var mainVM = DataContext as MainViewModel;
if (mainVM == null) return;
// 获取当前选中的工位索引(假设选项卡控件是 TabControl名称为 stationTabControl
// 需要在 XAML 中为 TabControl 设置 x:Name="stationTabControl"
int currentStation = stationTabControl.SelectedIndex + 1; // 假设索引从0开始
int currentStation = stationTabControl.SelectedIndex + 1;
var historyWin = new HistoryWindow { SelectedStation = currentStation };
historyWin.ShowDialog();
}
private void Window_KeyDown(object sender, KeyEventArgs e)
{
// 仅管理员可使用 Ctrl+P 打开参数设置窗口
if (Keyboard.Modifiers == ModifierKeys.Control && e.Key == Key.P)
{
var win = new ParameterWindow();
win.Owner = this;
win.ShowDialog();
if (App.CurrentUserRole == Models.UserRole.Admin)
{
var win = new ParameterWindow();
win.Owner = this;
win.ShowDialog();
}
else
{
MessageBox.Show("权限不足,无法打开参数设置", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
}
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selectedStation = stationTabControl.SelectedItem as MainViewModel.StationItem;
@@ -72,26 +87,15 @@ namespace MembranePoreTester.Views
var selectedTabItem = innerTabControl.SelectedItem as TabItem;
bool isPoreDistributionActive = selectedTabItem?.Header?.ToString() == "孔分布测试";
// 关键:设置 StationItem 的状态
selectedStation.IsPoreDistributionActive = isPoreDistributionActive;
selectedStation.PoreDistributionVM.IsActive = isPoreDistributionActive;
if (isPoreDistributionActive)
{
// 切换到孔分布时,清空之前的数据
//selectedStation.PoreDistributionVM.ClearData();
}
else
{
// 离开孔分布界面时,停止自动采集
//selectedStation.PoreDistributionVM.StopCollecting();
}
// 清空数据和停止采集的代码已注释,保持原样
}
}
}
}
// 辅助方法:查找 Visual Tree 中的指定类型元素
private T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
@@ -106,6 +110,11 @@ namespace MembranePoreTester.Views
private void OpenValveControl_Click(object sender, RoutedEventArgs e)
{
if (App.CurrentUserRole != Models.UserRole.Admin)
{
MessageBox.Show("权限不足,无法打开阀门控制", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
var win = new ValveControlWindow();
win.Owner = this;
win.Show();

View File

@@ -19,6 +19,10 @@ namespace MembranePoreTester.Views
{
System.Diagnostics.Debug.WriteLine($"工位{vm.StationId} IsVisible={this.IsVisible}");
vm.IsActive = this.IsVisible;
if (this.IsVisible)
{
vm.RefreshPlot(); // 新增这一行
}
}
};