|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
namespace SlnMesnac.WPF.ViewModel
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 生产管理ViewModel
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class ProdMgmtViewModel : ViewModelBase
|
|
|
|
|
{
|
|
|
|
|
private readonly ILogger<ProdMgmtViewModel> _logger;
|
|
|
|
|
|
|
|
|
|
private readonly ProdMgmtBusiness? _prodMgmtBusiness;
|
|
|
|
|
|
|
|
|
|
private readonly PalletStowBusiness? _palletStowBusiness;
|
|
|
|
|
|
|
|
|
|
private readonly ProdCompletionBusiness? _prodCompletionBusiness;
|
|
|
|
|
|
|
|
|
|
private ObservableCollection<dynamic> listItems = new ObservableCollection<dynamic>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region 参数定义
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 工位名称
|
|
|
|
|
/// </summary>
|
|
|
|
|
private string stationName = string.Empty;
|
|
|
|
|
public string StationName
|
|
|
|
|
{
|
|
|
|
|
get { return stationName; }
|
|
|
|
|
set { stationName = value; RaisePropertyChanged(nameof(StationName)); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 订单编号
|
|
|
|
|
/// </summary>
|
|
|
|
|
private string orderCode = string.Empty;
|
|
|
|
|
public string OrderCode
|
|
|
|
|
{
|
|
|
|
|
get { return orderCode; }
|
|
|
|
|
set { orderCode = value; RaisePropertyChanged(nameof(OrderCode)); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 计划编号
|
|
|
|
|
/// </summary>
|
|
|
|
|
private string planCode = string.Empty;
|
|
|
|
|
public string PlanCode
|
|
|
|
|
{
|
|
|
|
|
get { return planCode; }
|
|
|
|
|
set { planCode = value; RaisePropertyChanged(nameof(PlanCode)); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 产品型号
|
|
|
|
|
/// </summary>
|
|
|
|
|
private string productModel = string.Empty;
|
|
|
|
|
public string ProductModel
|
|
|
|
|
{
|
|
|
|
|
get { return productModel; }
|
|
|
|
|
set { productModel = value; RaisePropertyChanged(nameof(ProductModel)); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 开始时间
|
|
|
|
|
/// </summary>
|
|
|
|
|
private string beginTime = string.Empty;
|
|
|
|
|
public string BeginTime
|
|
|
|
|
{
|
|
|
|
|
get { return beginTime; }
|
|
|
|
|
set { beginTime = value; RaisePropertyChanged(nameof(BeginTime)); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 计划数量
|
|
|
|
|
/// </summary>
|
|
|
|
|
private int planAmount = 0;
|
|
|
|
|
public int PlanAmount
|
|
|
|
|
{
|
|
|
|
|
get { return planAmount; }
|
|
|
|
|
set { planAmount = value; RaisePropertyChanged(nameof(planAmount)); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 完成数量
|
|
|
|
|
/// </summary>
|
|
|
|
|
public int complateAmout;
|
|
|
|
|
public int ComplateAmout
|
|
|
|
|
{
|
|
|
|
|
get { return complateAmout; }
|
|
|
|
|
set { complateAmout = value; RaisePropertyChanged(nameof(ComplateAmout)); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 差异值
|
|
|
|
|
/// </summary>
|
|
|
|
|
public int diffAmount;
|
|
|
|
|
public int DiffAmount
|
|
|
|
|
{
|
|
|
|
|
get { return diffAmount; }
|
|
|
|
|
set { diffAmount = value; RaisePropertyChanged(nameof(DiffAmount)); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 完成率
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string compleRoution;
|
|
|
|
|
public string CompleRoution
|
|
|
|
|
{
|
|
|
|
|
get { return compleRoution; }
|
|
|
|
|
set { compleRoution = value; RaisePropertyChanged(nameof(CompleRoution)); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 计划列表DataGrid
|
|
|
|
|
/// </summary>
|
|
|
|
|
private ObservableCollection<MesProductPlanDto> planInfoDataGrid;
|
|
|
|
|
|
|
|
|
|
public ObservableCollection<MesProductPlanDto> PlanInfoDataGrid
|
|
|
|
|
{
|
|
|
|
|
get { return planInfoDataGrid; }
|
|
|
|
|
set { planInfoDataGrid = value; RaisePropertyChanged(() => PlanInfoDataGrid); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// LisBox数据模板
|
|
|
|
|
/// </summary>
|
|
|
|
|
private IEnumerable logInfoListBox;
|
|
|
|
|
public IEnumerable LogInfoListBox
|
|
|
|
|
{
|
|
|
|
|
get { return logInfoListBox; }
|
|
|
|
|
set { logInfoListBox = value; RaisePropertyChanged(() => LogInfoListBox); }
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 事件定义
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 开始执行生产计划
|
|
|
|
|
/// </summary>
|
|
|
|
|
public RelayCommand<string> StartProdPlanCommand { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 暂停生产计划
|
|
|
|
|
/// </summary>
|
|
|
|
|
public RelayCommand<string> StopProdPlanCommand { get; set; }
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
public ProdMgmtViewModel()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
StartProdPlanCommand = new RelayCommand<string>(obj => StartProdPlan(obj));
|
|
|
|
|
StopProdPlanCommand = new RelayCommand<string>(obj => StopProdPlan(obj));
|
|
|
|
|
_logger = App.ServiceProvider.GetService<ILogger<ProdMgmtViewModel>>();
|
|
|
|
|
_prodMgmtBusiness = App.ServiceProvider.GetService<ProdMgmtBusiness>();
|
|
|
|
|
_palletStowBusiness = App.ServiceProvider.GetService<PalletStowBusiness>();
|
|
|
|
|
_prodCompletionBusiness = App.ServiceProvider.GetService<ProdCompletionBusiness>();
|
|
|
|
|
Task.Run(() =>
|
|
|
|
|
{
|
|
|
|
|
_prodMgmtBusiness.RefreshProdPlanListEvent += RefreshPlanDataGrid;
|
|
|
|
|
_prodMgmtBusiness.MatPutInValidEvent += MatPutInValidHandleEvent;
|
|
|
|
|
_prodMgmtBusiness.PrintMessageToListBoxEvent += PrintMessageToListBox;
|
|
|
|
|
_prodMgmtBusiness.InitProdPlan();
|
|
|
|
|
});
|
|
|
|
|
//Task.Run(() =>
|
|
|
|
|
//{
|
|
|
|
|
// _palletStowBusiness.PrintMessageToListBoxEvent += PrintMessageToListBox;
|
|
|
|
|
// _palletStowBusiness.Init();
|
|
|
|
|
//});
|
|
|
|
|
Task.Run(() =>
|
|
|
|
|
{
|
|
|
|
|
_prodCompletionBusiness.PrintMessageToListBoxEvent += PrintMessageToListBox;
|
|
|
|
|
// _prodCompletionBusiness.Init();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void test()
|
|
|
|
|
{
|
|
|
|
|
// gunHelper.InstanceSerialPort();
|
|
|
|
|
// HttpHelper.JudgeAgvTaskComplete();
|
|
|
|
|
// HttpHelper.SendAgvTask("20245603");
|
|
|
|
|
//HttpHelper.JudgeAgvTaskComplete();
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 刷新计划执行
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="prodPlan"></param>
|
|
|
|
|
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 = "50";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
OrderCode = string.Empty;
|
|
|
|
|
PlanCode = string.Empty;
|
|
|
|
|
ProductModel = string.Empty;
|
|
|
|
|
BeginTime = string.Empty;
|
|
|
|
|
PlanAmount = 0;
|
|
|
|
|
ComplateAmout = 0;
|
|
|
|
|
DiffAmount = 0;
|
|
|
|
|
CompleRoution = string.Empty;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 刷新生产计划
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="list"></param>
|
|
|
|
|
private void RefreshPlanDataGrid(List<MesProductPlanDto> list)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
PlanInfoDataGrid = new ObservableCollection<MesProductPlanDto>();
|
|
|
|
|
if (list != null)
|
|
|
|
|
{
|
|
|
|
|
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}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 开始生产计划事件
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="obj"></param>
|
|
|
|
|
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}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 暂停生产计划事件
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="obj"></param>
|
|
|
|
|
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}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 校验失败人工确认事件
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="validType"></param>
|
|
|
|
|
/// <param name="productPlan"></param>
|
|
|
|
|
/// <param name="materialName"></param>
|
|
|
|
|
/// <param name="msg"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 系统运行日志输出
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="message"></param>
|
|
|
|
|
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}");
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|