using MahApps.Metro.Controls; using MaterialDesignThemes.Wpf; using NPOI.SS.Formula.Functions; using OxyPlot; using OxyPlot.Axes; using OxyPlot.Legends; using OxyPlot.Series; using OxyPlot.Wpf; using Prism.Commands; using Prism.Events; using Prism.Ioc; using Prism.Mvvm; using Prism.Regions; using Prism.Services.Dialogs; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Threading.Tasks; using System.Windows; using System.Windows.Media; using TeamAAS_VP; using TeamAAS_VP.Controls; using TeamAAS_VP.Core; using TeamAAS_VP.Data; using TeamAAS_VP.Enums; using TeamAAS_VP.Events; using TeamAAS_VP.Interfaces; using TeamAAS_VP.Models; using TeamAAS_VP.Resources.Languages; using TeamAAS_VP.Services; using TeamAAS_VP.ViewModels.DebugMod; using TeamAAS_VP.Views.DebugMod; using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel; namespace TeamAAS_VP.ViewModels { public class HomeViewModel : BindableBase, IConfirmNavigationRequest { IEventAggregator _eventAggregator; IContainerProvider _container; IProductService _productService; IConfigService _configService; IRemoteCommandService _remoteCommandService; ISystemDatabaseService _systemDatabaseService; IDialogService _dialogService; #region 属性 private ObservableCollection messageQueue=new ObservableCollection(); /// /// 运行信息队列 /// public ObservableCollection MessageQueue { get { return messageQueue; } set { SetProperty(ref messageQueue,value); } } private ObservableCollection _ProductList; public ObservableCollection ProductList { get { return _ProductList; } set { SetProperty(ref _ProductList, value); } } private Management _management; public Management management { get { return _management; } set { SetProperty(ref _management, value); } } private double _CTTotalSeconds; public double CTTotalSeconds { get { return _CTTotalSeconds; } set { SetProperty(ref _CTTotalSeconds, value); } } private ProductModel _SelectProduct; public ProductModel SelectProduct { get { return _SelectProduct; } set { SetProperty(ref _SelectProduct,value); } } private bool CanLoad { get { if (SelectProduct!=null && IsLoadProduct) { return true; } else { return false; } } } private bool _IsLoadProduct = true; public bool IsLoadProduct { get { return _IsLoadProduct; } set { SetProperty(ref _IsLoadProduct, value); } } private bool _isCanExecute = true; public bool isCanExecute { get { return _isCanExecute; } set { SetProperty(ref _isCanExecute, value); } } private ProductModel _CurrentProduct; public ProductModel CurrentProduct { get { return _CurrentProduct; } set { SetProperty(ref _CurrentProduct, value); } } private PlotModel _LockCurvePlotModel; /// /// 锁付曲线 /// public PlotModel LockCurvePlotModel { get { return _LockCurvePlotModel; } set { SetProperty(ref _LockCurvePlotModel, value); } } private ObservableCollection _LockResults = new ObservableCollection(); /// /// 锁付结果列表 /// public ObservableCollection LockResults { get { return _LockResults; } set { SetProperty(ref _LockResults, value); } } private bool _IsAllowEdit = false; public bool IsAllowEdit { get { return _IsAllowEdit; } set { SetProperty(ref _IsAllowEdit, value); } } #endregion #region 命令 public DelegateCommand LoadedCommand { get; set; } private DelegateCommand _LoadProductCommand; public DelegateCommand LoadProductCommand => _LoadProductCommand ?? (_LoadProductCommand = new DelegateCommand(ExecuteLoadProductCommand).ObservesCanExecute(()=> CanLoad).ObservesProperty(()=> SelectProduct).ObservesProperty(()=> IsLoadProduct)); private DelegateCommand _ResetCounterCommand; public DelegateCommand ResetCounterCommand => _ResetCounterCommand ?? (_ResetCounterCommand = new DelegateCommand(ExecuteResetCounterCommand).ObservesCanExecute(() => DoCondition).ObservesProperty(()=>isCanExecute)); private bool DoCondition { get { return isCanExecute; } } private DelegateCommand _CopyCommand; public DelegateCommand CopyCommand => _CopyCommand ?? (_CopyCommand = new DelegateCommand(ExecuteCopyCommand)); private DelegateCommand _TorqueInspectionCommand; public DelegateCommand TorqueInspectionCommand => _TorqueInspectionCommand ?? (_TorqueInspectionCommand = new DelegateCommand(ExecuteTorqueInspectionCommand)); //更换吸嘴 private DelegateCommand _ChangeNozzleCommand; public DelegateCommand ChangeNozzleCommand => _ChangeNozzleCommand ?? (_ChangeNozzleCommand = new DelegateCommand(ExecuteChangeNozzleCommand)); //更换披头 private DelegateCommand _ChangeHeaderCommand; public DelegateCommand ChangeHeaderCommand => _ChangeHeaderCommand ?? (_ChangeHeaderCommand = new DelegateCommand(ExecuteChangeHeaderCommand)); //添加螺丝 private DelegateCommand _AddScrewCommand; public DelegateCommand AddScrewCommand => _AddScrewCommand ?? (_AddScrewCommand = new DelegateCommand(ExecuteAddScrewCommand)); private DelegateCommand _SetAlarmValueCommand; public DelegateCommand SetAlarmValueCommand => _SetAlarmValueCommand ?? (_SetAlarmValueCommand = new DelegateCommand(ExecuteSetAlarmValueCommand)); #endregion #region 事件 #endregion public HomeViewModel(IEventAggregator ea, IContainerProvider container, IProductService productService, IConfigService configService, IRemoteCommandService remoteCommandService , ISystemDatabaseService systemDatabaseService,IDialogService dialogService) { _eventAggregator = ea; _container = container; _dialogService = dialogService; _productService = productService; LoadedCommand = new DelegateCommand(OnLoad); _eventAggregator.GetEvent().Subscribe(AddMessageInvoke); //订阅权限登录事件 _eventAggregator.GetEvent().Subscribe(LoginChange); management = _container.Resolve(); _configService = configService; _productService.OnProductChanged += _productService_OnProductChanged; _remoteCommandService = remoteCommandService; _remoteCommandService.CycleTimingTicked += _remoteCommandService_CycleTimingTicked; _systemDatabaseService = systemDatabaseService; _eventAggregator.GetEvent().Subscribe(OnLockFinish); } private void _remoteCommandService_CycleTimingTicked(object sender, TimeSpan e) { try { if (App.Current!=null) { App.Current.Invoke(() => { CTTotalSeconds = e.TotalSeconds; }); } } catch (Exception) { } } #region 方法 bool isFirst=true; private void OnLoad() { if (!isFirst) { return; } InitLockCurvePlotModel(); isFirst = false; if (_systemDatabaseService.GetCurrentUser().userPart == Enums.UserPart.Operator) { IsAllowEdit = false; } else { IsAllowEdit = true; } } async void ExecuteLoadProductCommand(ProductModel product) { if (product == null) return; var view = new ShowMessage(Lang.是否加载产品, $"{Lang.加载产品}:{product.Name}?"); //show the dialog var result = await DialogHost.Show(view, "RootDialog", null, null, null); if (result != null && result is bool) { if (((bool)result)) { IsLoadProduct = false; var waiting = new WaitingControl(); //show the dialog var task = DialogHost.Show(waiting, "RootDialog", null, null, null); _productService.LoadProduct(product.ID); _productService.SetCurrentProduct(product.ID); await management.WritePositionToPlcAsync(); if (DialogHost.IsDialogOpen("RootDialog")) { DialogHost.Close("RootDialog"); } await task; //DatabaseHelper.AddLoadProductRecord(product.ID, product.Name, false); IsLoadProduct = true; } } } void ExecuteCopyCommand(string textToCopy) { Clipboard.SetText(textToCopy); } /// /// 添加消息至消息队列 /// /// /// public void AddMessage(string msg, Color color) { App.Current.Dispatcher.BeginInvoke(new Action(() => { try { MessageQueue.Add(new TaskMessage() { DT = DateTime.Now, Message = msg, FontColol = new SolidColorBrush(color) }); LogHelper.WriteLogInfo(msg); } catch (Exception) { } })); } /// /// 添加消息至消息队列 /// /// /// public void AddMessage(string msg, MessageLevel level) { MessageStruct messageStruct = new MessageStruct() { Message = msg, level = level }; App.Current.Dispatcher.BeginInvoke(new Action(() => { AddMessage(messageStruct); })); } /// /// 添加消息至消息队列 /// /// public void AddMessage(MessageStruct messageStruct) { try { if (MessageQueue.Count >= 100) { MessageQueue.RemoveAt(0);// 从队列头部移除最早的消息 } Color color = Colors.Black; switch (messageStruct.level) { case MessageLevel.Info: color = Colors.Black; break; case MessageLevel.Debug: color = Colors.Green; break; case MessageLevel.Alarm: color = Colors.Orange; break; case MessageLevel.Error: color = Colors.Red; break; } MessageQueue.Add(new TaskMessage() { DT = DateTime.Now, Message = messageStruct.Message, FontColol = new SolidColorBrush(color) }); LogHelper.WriteLogInfo(messageStruct.Message); } catch (Exception) { } } public void AddMessageInvoke(MessageStruct messageStruct) { App.Current.Dispatcher.BeginInvoke(new Action(() => { AddMessage(messageStruct); })); } private void LoginChange(Models.User user) { if (user.userPart == Enums.UserPart.Operator) { IsAllowEdit = false; } else { IsAllowEdit = true; } } /// /// 重置计数 /// async void ExecuteResetCounterCommand() { var currentProduct =_productService.GetCurrentProduct(); if (currentProduct == null) return; var view = new ShowMessage(Lang.计数清零, Lang.是否重置当前产品的计数); //show the dialog var result = await DialogHost.Show(view, "RootDialog", null, null, null); if (result != null && result is bool) { if (((bool)result)) { isCanExecute = false; await _systemDatabaseService.ResetProductionAsync(currentProduct.Name); isCanExecute = true; } } } /// /// 初始化曲线图 /// private void InitLockCurvePlotModel() { var model = new PlotModel { Title = Lang.锁付曲线, TitleFontSize = 16}; // 设置图例 var legend = new Legend { LegendPosition = LegendPosition.TopRight, LegendPlacement = LegendPlacement.Outside, LegendOrientation = LegendOrientation.Vertical, LegendBorderThickness = 0 }; model.Legends.Add(legend); // 设置X轴 var xAxis = new LinearAxis { Key="X", Position = AxisPosition.Bottom, Title = Lang.锁付圈数, Minimum = 0, MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Dot }; model.Axes.Add(xAxis); // 设置Y轴 var yAxis = new LinearAxis { Key = "Y", Position = AxisPosition.Left, Title = Lang.力矩kgf, MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Dot }; model.Axes.Add(yAxis); // 添加示例数据系列 var series = new LineSeries { Title = Lang.锁付力矩曲线, StrokeThickness = 2, MarkerSize = 3, MarkerType = MarkerType.Circle, CanTrackerInterpolatePoints = false, }; model.Series.Add(series); LockCurvePlotModel = model; } /// /// 螺丝锁付完成时调用 /// /// /// private void OnLockFinish(LockResult result) { //如果当前螺丝编号为1,则清除之前的结果 if (result.Number == 1) { LockResults.Clear(); } LockResults.Add(result); //更新曲线图 App.Current.Dispatcher.BeginInvoke(new Action(() => { try { var series = LockCurvePlotModel.Series[0] as LineSeries; series.Points.Clear(); foreach (var waveData in result.WaveDatas) { series.Points.Add(new OxyPlot.DataPoint(waveData.Turns, waveData.Torque)); } // 重置所有轴的范围以适应新数据 LockCurvePlotModel.ResetAllAxes(); LockCurvePlotModel.InvalidatePlot(true); if (!string.IsNullOrEmpty(result.LockCurveImagePath)) { PngExporter.Export(LockCurvePlotModel, result.LockCurveImagePath, (int)LockCurvePlotModel.Width, (int)LockCurvePlotModel.Height); } } catch (Exception ex) { LogHelper.WriteLogError("更新曲线图和保存曲线图时出错!", ex); } })); } /// /// 添加螺丝 /// private void ExecuteAddScrewCommand() { _dialogService.ShowDialog("AddScrew", rst => { //对话框关闭之后的回调函数,可以在这解析结果。 ButtonResult result1 = rst.Result; if (result1 == ButtonResult.OK) { _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = Lang.完成, Duration = 1 }); } }); } /// /// 更换披头 /// void ExecuteChangeHeaderCommand() { _dialogService.ShowDialog("ChangeHeader", rst => { //对话框关闭之后的回调函数,可以在这解析结果。 ButtonResult result1 = rst.Result; if (result1 == ButtonResult.OK) { _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = Lang.完成, Duration = 1 }); } }); } /// /// 更换吸嘴 /// void ExecuteChangeNozzleCommand() { _dialogService.ShowDialog("ChangeNozzle", rst => { //对话框关闭之后的回调函数,可以在这解析结果。 ButtonResult result1 = rst.Result; if (result1 == ButtonResult.OK) { _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = Lang.完成, Duration = 1 }); } }); } void ExecuteTorqueInspectionCommand() { _dialogService.ShowDialog("TorqueCheck", rst => { //对话框关闭之后的回调函数,可以在这解析结果。 ButtonResult result1 = rst.Result; if (result1 == ButtonResult.OK) { _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = Lang.完成, Duration = 1 }); } }); } void ExecuteSetAlarmValueCommand() { _dialogService.ShowDialog("SetAlarmValue", rst => { //对话框关闭之后的回调函数,可以在这解析结果。 ButtonResult result1 = rst.Result; if (result1 == ButtonResult.OK) { _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = Lang.完成, Duration = 1 }); } }); } #endregion #region 继承 /// /// 确认导航请求时调用。此方法允许您在导航之前执行一些操作。 /// /// /// public void ConfirmNavigationRequest(NavigationContext navigationContext, Action continuationCallback) { continuationCallback(true); } /// /// 接收导航请求时调用。传入导航参数,包含有关导航目标的信息。 /// /// /// public async void OnNavigatedTo(NavigationContext navigationContext) { try { ProductList = new ObservableCollection(_productService.GetAllProducts()); } catch (Exception ex) { LogHelper.WriteLogError(Lang.主界面界面进入时出错, ex); } } /// /// 是否允许导航到此视图模型。 /// /// /// public bool IsNavigationTarget(NavigationContext navigationContext) { return true; } /// /// 导航离开此视图模型时调用。您可以在此处执行清理操作或保存状态。 /// /// public void OnNavigatedFrom(NavigationContext navigationContext) { } #endregion private void _productService_OnProductChanged(ProductModel obj) { App.Current.Dispatcher.BeginInvoke(new Action(() => { CurrentProduct = obj; })); } } }