using GalaSoft.MvvmLight; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using SlnMesnac.Model.domain; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; using System.Windows; using GalaSoft.MvvmLight.Command; using SlnMesnac.Business; using SlnMesnac.Model.dto; using SlnMesnac.Model.enums; using SlnMesnac.WPF.Page; using Newtonsoft.Json.Linq; using System.Collections; using Microsoft.IdentityModel.Logging; using System.Windows.Documents; using SlnMesnac.Common; using HslCommunication.Profinet.GE; using static System.Net.Mime.MediaTypeNames; using Application = System.Windows.Application; using LiveCharts; using System.Threading; using SlnMesnac.Repository.service; using LiveCharts.Defaults; using static MaterialDesignThemes.Wpf.Theme.ToolBar; using LiveCharts.Wpf; using System.Windows.Media; using System.Windows.Threading; using Microsoft.AspNetCore.Mvc.ModelBinding; using SlnMesnac.Config; namespace SlnMesnac.WPF.ViewModel { /// /// 生产管理ViewModel /// public class ProdMgmtViewModel : ViewModelBase { private readonly ILogger _logger; private readonly ProdMgmtBusiness? _prodMgmtBusiness; private readonly PalletStowBusiness? _palletStowBusiness; private readonly IMesBaseBarcodeInfoService? _mesBaseBarcodeInfoService; private readonly ProdCompletionBusiness? _prodCompletionBusiness; private ObservableCollection listItems = new ObservableCollection(); #region 参数定义 #region 日产量柱状图X轴日期 /// /// 日产量柱状图X轴日期 /// private List productionHourList = new List(); public List ProductionHourList { get { return productionHourList; } set { productionHourList = value; } } #endregion #region 型号统计柱状图 /// /// 型号统计柱状图 /// private SeriesCollection achievement = new SeriesCollection(); public SeriesCollection Achievement { get { return achievement; } set { achievement = value; } } #endregion /// /// 工位名称 /// private string stationName = string.Empty; public string StationName { get { return stationName; } set { stationName = value; RaisePropertyChanged(nameof(StationName)); } } /// /// 订单编号 /// private string orderCode = string.Empty; public string OrderCode { get { return orderCode; } set { orderCode = value; RaisePropertyChanged(nameof(OrderCode)); } } /// /// 计划编号 /// private string planCode = string.Empty; public string PlanCode { get { return planCode; } set { planCode = value; RaisePropertyChanged(nameof(PlanCode)); } } /// /// 产品型号 /// private string productModel = string.Empty; public string ProductModel { get { return productModel; } set { productModel = value; RaisePropertyChanged(nameof(ProductModel)); } } /// /// 开始时间 /// private string beginTime = string.Empty; public string BeginTime { get { return beginTime; } set { beginTime = value; RaisePropertyChanged(nameof(BeginTime)); } } /// /// 计划数量 /// private int planAmount = 0; public int PlanAmount { get { return planAmount; } set { planAmount = value; RaisePropertyChanged(nameof(planAmount)); } } /// /// 完成数量 /// public int complateAmout; public int ComplateAmout { get { return complateAmout; } set { complateAmout = value; RaisePropertyChanged(nameof(ComplateAmout)); } } /// /// 差异值 /// public int diffAmount; public int DiffAmount { get { return diffAmount; } set { diffAmount = value; RaisePropertyChanged(nameof(DiffAmount)); } } /// /// 完成率 /// public decimal compleRoution; public decimal CompleRoution { get { return compleRoution; } set { compleRoution = value; RaisePropertyChanged(nameof(CompleRoution)); } } /// /// 计划列表DataGrid /// private ObservableCollection planInfoDataGrid; public ObservableCollection PlanInfoDataGrid { get { return planInfoDataGrid; } set { planInfoDataGrid = value; RaisePropertyChanged(() => PlanInfoDataGrid); } } /// /// LisBox数据模板 /// private IEnumerable logInfoListBox; public IEnumerable LogInfoListBox { get { return logInfoListBox; } set { logInfoListBox = value; RaisePropertyChanged(() => LogInfoListBox); } } #endregion #region 事件定义 /// /// 开始执行生产计划 /// public RelayCommand StartProdPlanCommand { get; set; } /// /// 暂停生产计划 /// public RelayCommand StopProdPlanCommand { get; set; } #endregion public ProdMgmtViewModel() { StartProdPlanCommand = new RelayCommand(obj => StartProdPlan(obj)); StopProdPlanCommand = new RelayCommand(obj => StopProdPlan(obj)); _logger = App.ServiceProvider.GetService>(); _prodMgmtBusiness = App.ServiceProvider.GetService(); _palletStowBusiness = App.ServiceProvider.GetService(); _prodCompletionBusiness = App.ServiceProvider.GetService(); _mesBaseBarcodeInfoService = App.ServiceProvider.GetService(); Task.Run(() => { _prodMgmtBusiness.RefreshProdPlanListEvent += RefreshPlanDataGrid; _prodMgmtBusiness.MatPutInValidEvent += MatPutInValidHandleEvent; _prodMgmtBusiness.PrintMessageToListBoxEvent += PrintMessageToListBox; _prodMgmtBusiness.InitProdPlan(); }); Task.Run(() => { _prodCompletionBusiness.PrintMessageToListBoxEvent += PrintMessageToListBox; // _prodCompletionBusiness.Init(); }); Init(); } private void Init() { RefreChart(); DispatcherTimer _timer = new DispatcherTimer(); _timer.Interval = TimeSpan.FromMinutes(5); _timer.Tick += Timer_Tick; _timer.Start(); } private void Timer_Tick(object sender, EventArgs e) { RefreChart(); } public void test() { // gunHelper.InstanceSerialPort(); // HttpHelper.JudgeAgvTaskComplete(); // HttpHelper.SendAgvTask("20245603"); //HttpHelper.JudgeAgvTaskComplete(); } /// /// 刷新计划执行 /// /// private void RefreshPlanExec(MesProductPlanDto prodPlan) { if (prodPlan != null) { StationName = "磁悬"; OrderCode = prodPlan.OrderCode; PlanCode = prodPlan.PlanCode; ProductModel = prodPlan.MaterialName; BeginTime = prodPlan.RealBeginTime.ToString("yyyy-MM-dd HH:mm:ss"); PlanAmount = Convert.ToInt32(prodPlan.PlanAmount); ComplateAmout = Convert.ToInt32(prodPlan.CompleteAmount); DiffAmount = Convert.ToInt32(prodPlan.PlanAmount) - Convert.ToInt32(prodPlan.CompleteAmount); CompleRoution = Math.Round((prodPlan.CompleteAmount / prodPlan.PlanAmount) * 100, 2); } else { OrderCode = string.Empty; PlanCode = string.Empty; ProductModel = string.Empty; BeginTime = string.Empty; PlanAmount = 0; ComplateAmout = 0; DiffAmount = 0; CompleRoution = 0; } } /// /// 刷新生产计划 /// /// private async void RefreshPlanDataGrid(List list) { try { await App.Current.Dispatcher.BeginInvoke((Action)(() => { PlanInfoDataGrid = new ObservableCollection(); if (list != null) { #region 按钮状态 // 假设初始状态所有计划的按钮状态 list.ForEach(plan => { plan.StartEnable = true; plan.StopEnable = false; }); // 查找是否存在正在执行的计划 var executingPlan = list.FirstOrDefault(x => x.PlanStatus == PlanStatusEnum.已开始); if (executingPlan != null) { // 如果有正在执行的计划,只有该计划的暂停按钮可以点击,其他计划的按钮都不能点击 foreach (var plan in list) { if (plan == executingPlan) { plan.StopEnable = true; // 执行中的计划可以暂停 plan.StartEnable = false; } else { plan.StartEnable = false; // 其他计划不能开始 } } } #endregion list.OrderByDescending(x => x.PlanStatus); list.ForEach( arg => { PlanInfoDataGrid.Add(arg); }); var info = list.Where(x => x.PlanStatus == PlanStatusEnum.已开始).ToList(); if (info.Count > 0) { RefreshPlanExec(info.First()); } } })); } catch (Exception ex) { _logger.LogError($"生产计划刷新异常:{ex.Message}"); } } /// /// 开始生产计划事件 /// /// private void StartProdPlan(string obj) { try { //先检查是否有正在执行的计划 var hasPlan = planInfoDataGrid.Where(x => x.PlanStatus == PlanStatusEnum.已开始).FirstOrDefault(); if (hasPlan != null) { var result = MessageBox.Show("有正在执行的计划,是否确认切换计划!", "确认", MessageBoxButton.YesNo); if (result == MessageBoxResult.Yes) { hasPlan.PlanStatus = PlanStatusEnum.待执行; _prodMgmtBusiness.UpdateProdPlan(hasPlan); } else { return; } } _logger.LogInformation($"开始执行{obj}计划"); var info = planInfoDataGrid.Where(x => x.PlanCode == obj).First(); if (info != null) { info.PlanStatus = PlanStatusEnum.已开始; info.PlanBeginTime = DateTime.Now; } _prodMgmtBusiness.UpdateProdPlan(info); PrintMessageToListBox($"开始执行{obj}计划"); this.RefreshPlanExec(info); } catch (Exception e) { _logger.LogError($"开始事件处理异常:{e.Message}"); } } /// /// 暂停生产计划事件 /// /// private void StopProdPlan(string obj) { try { _logger.LogInformation($"暂停执行{obj}计划"); var info = planInfoDataGrid.Where(x => x.PlanCode == obj).First(); if (info != null) { info.PlanStatus = PlanStatusEnum.待执行; //info.RealBeginTime = DateTime.Now; } PrintMessageToListBox($"暂停执行{obj}计划"); _prodMgmtBusiness.UpdateProdPlan(info); this.RefreshPlanExec(null); } catch (Exception e) { _logger.LogError($"暂停事件处理异常:{e.Message}"); } } /// /// 校验失败人工确认事件 /// /// /// /// /// /// private bool MatPutInValidHandleEvent(int validType, MesProductPlan productPlan, string materialName, string msg) { var result = false; Application.Current.Dispatcher.Invoke(() => { var alarmWindow = new SystemAlarmWindow(); var viewModel = new SystemAlarmViewModel(); viewModel.AlarmMsg = msg; viewModel.AlarmConfirmed += (sender, isConfirmed) => { result = isConfirmed; alarmWindow.Close(); }; alarmWindow.DataContext = viewModel; alarmWindow.ShowDialog(); }); return result; } /// /// 系统运行日志输出 /// /// private async void PrintMessageToListBox(string message) { await Task.Run(() => { try { string formattedMessage = $"{DateTime.Now.ToString("HH:mm:ss.ss")} ==> {message}"; lock (listItems) { listItems.Add(formattedMessage); while (listItems.Count > 120) { listItems.RemoveAt(0); } var orderedList = listItems.OrderByDescending(x => x).ToList(); // 排序后转为 List Application.Current.Dispatcher.Invoke(() => { LogInfoListBox = orderedList; // 更新 UI }); } } catch (Exception ex) { _logger.LogError($"日志数据绑定异常:{ex.Message}"); } }); } /// /// 刷新产量统计图表 /// private async void RefreChart() { try { await Task.Run(() => { ProductionHourList = new List() { "8:00", "9:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00", "17:00", "18:00", "20:00" }; List list = _mesBaseBarcodeInfoService.Query(x => x.bindTime != null && x.bindTime >= DateTime.Now.Date && x.bindTime <= DateTime.Now.AddDays(1)).ToList(); if (list != null && list.Count > 0) { Dictionary hourProductionCount = new Dictionary(); // 初始化字典,每个小时的产量初始为0 foreach (var hour in ProductionHourList) { hourProductionCount[hour] = 0; } // 遍历查询结果,统计每个小时的产量 foreach (var item in list) { // 获取 bindTime 的小时部分 string hour = item.bindTime.Value.ToString("H:00"); // 如果小时在 ProductionHourList 中,则统计该小时的产量 if (hourProductionCount.ContainsKey(hour)) { hourProductionCount[hour]++; } } Application.Current.Dispatcher.Invoke(() => { Achievement.Clear(); ChartValues achievement = new ChartValues(); int i = 0; foreach (var kvp in hourProductionCount) { achievement.Add(new ObservablePoint(i++, kvp.Value)); } //加一个汇总柱状图 ProductionHourList.Add("合计"); achievement.Add(new ObservablePoint(i, list.Count)); var column = new ColumnSeries(); column.DataLabels = true; column.Title = "小时产量"; column.Values = achievement; column.Foreground = Brushes.White; Achievement.Add(column); }); } else { // ProductionHourList.Clear(); Achievement.Clear(); } }); }catch(Exception ex) { _logger.LogError($"产量统计图表异常:{ex.Message}"); } } } }