using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Microsoft.EntityFrameworkCore; using Microsoft.Xaml.Behaviors.Layout; using Newtonsoft.Json; using Serilog; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Configuration; using System.Data; using System.Data.Common; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Text.Json.Serialization; using System.Threading.Tasks; using System.Windows; using System.Windows.Threading; using WPFWCSDemo.Common; using WPFWCSDemo.Data; using WPFWCSDemo.Models.Devices.CircleRGV; using WPFWCSDemo.Models.Devices.CircleRGVStation; using WPFWCSDemo.Models.Tables; using WPFWCSDemo.StateCode; using WPFWCSDemo.Utilities; using WPFWCSDemo.Utilities.Table; using WPFWCSDemo.Views.CustomComponent; using static System.Windows.Forms.VisualStyles.VisualStyleElement.TrackBar; namespace WPFWCSDemo.ViewModels { public partial class TaskViewModel : ObservableObject { /// /// 用于实时更新任务表的定时器 /// private DispatcherTimer dispatcherTimer; public TaskViewModel() { TaskRT = new ObservableCollection(); ColumnList = new List(); col = new Dictionary(); SourceLocations = new List(); TargetLocations = new List(); RGVNumbers = new List(); LoadTaskGrid(); LoadColumns(); LocationInitialize(); //Task.Run(() => LoadTaskGridAsync()); b = true; // 设置定时器属性 dispatcherTimer = new DispatcherTimer(); dispatcherTimer.Interval = TimeSpan.FromSeconds(6); // 设置时间间隔 dispatcherTimer.Tick += DispatcherTimer_Tick; // 添加事件处理程序 dispatcherTimer.Start(); // 启动计时器 } //调度任务表刷新参数 private void DispatcherTimer_Tick(object? sender, EventArgs e) { if (b) { LoadTaskGrid(); } } /// /// 是否更新任务表的标志 /// bool b; /// /// 调度任务字段---原数据/视图数据 /// [ObservableProperty] ObservableCollection _taskRT; /// /// 搜索关键字 /// [ObservableProperty] string? _keywords; /// /// 筛选列表集合 /// [ObservableProperty] List _columnList; /// /// 筛选列表集合对应的查询字段 /// Dictionary col; /// /// 筛选列表文本 /// [ObservableProperty] string? _columnName; /// /// 筛选列表文本选择项 /// [ObservableProperty] string? _columnNameSelected; /// /// 筛选列表选项 /// [ObservableProperty] int _taskTypeSelectedIndex; /// /// 右侧对话框弹出属性 /// [ObservableProperty] bool _isRightDrawerOpen; /// /// 顶部对话框弹出属性 /// [ObservableProperty] bool _isTopDrawerOpen; /// /// 站点初始化集合 /// [ObservableProperty] int _rowCount; [ObservableProperty] int _columnCount; [ObservableProperty] int _floorCount; [ObservableProperty] List _rows; [ObservableProperty] List _columns; [ObservableProperty] List _floors; /// /// 取放货站点集合 /// [ObservableProperty] List _sourceLocations; [ObservableProperty] List _targetLocations; /// /// 测试下发界面任务类型 /// [ObservableProperty] int _testingTaskTypeIndex; /// /// 任务类型 /// [ObservableProperty] int _selectedTaskTypeIndex; /// /// 输入托盘号 /// [ObservableProperty] string _inputTaskId; /// /// 取货站点 /// [ObservableProperty] int _selectedSourceLocation; /// /// 放货站点 /// [ObservableProperty] int _selectedTargetLocation; /// /// 小车编号集合 /// [ObservableProperty] List _rGVNumbers; /// /// 选中小车编号 /// [ObservableProperty] int _selectedRGVNumber; /// /// 右侧对话框弹出命令 /// [RelayCommand] private void NewTask() { IsRightDrawerOpen = true; } /// /// 顶部对话框弹出命令---堆垛机测试 /// [RelayCommand] private void StackerTesting() { IsTopDrawerOpen = true; } /// /// 更改任务类型选项直接更新表 /// //[RelayCommand] void TaskTypeSelectItemChanged() { using var context = new AppDbContext(); List tasks; if (TaskTypeSelectedIndex == 1) { tasks = context.Set() .OrderByDescending(t => t.CreateTime) .Where(t => t.TaskType == 10) .ToList(); } else if (TaskTypeSelectedIndex == 2) { tasks = context.Set() .OrderByDescending(t => t.CreateTime) .Where(t => t.TaskType == 11) .ToList(); } else { tasks = context.Set() .OrderByDescending(t => t.CreateTime) .ToList(); } TaskRT.Clear(); //遍历表中每行数据并初始化值 foreach (TaskRT task in tasks) { TaskRT.Add(task); } } /// /// 查询任务 /// [RelayCommand] public void Query() { //关键词不为空且列名不为空 if (!string.IsNullOrEmpty(Keywords) && !string.IsNullOrEmpty(ColumnName)) { using var context = new AppDbContext(); var tasks=context.Set() .FromSqlInterpolated($"SELECT * FROM TASK WHERE {col[ColumnName]} LIKE %{Keywords}% ORDER BY CREATETIME DESC") .ToList(); TaskRT.Clear(); //遍历表中每行数据并初始化值 foreach (TaskRT task in tasks) { TaskRT.Add(task); } } else { LoadTaskGrid(); } b = false; } /// /// 重置筛选项 /// [RelayCommand] void Clear() { Keywords = string.Empty; ColumnName = string.Empty; LoadTaskGrid(); b = true; } #region 添加新任务相关 // 下拉框获取值属性 (源/目标排、列、层) /// /// 点击新建任务按钮命令 /// [RelayCommand] public void AddTask() { InputCheck(); //MessageBox.Show(SelectedTaskType); //获取任务参数值 TaskRT taskRT = new TaskRT { TaskId = SqlHelper.GetTaskIdByManualGeneration().ToString(),//使用int类型初始值不是空 指定9起始的任务号为人工操作标识 SourceLocation = SelectedSourceLocation.ToString(), TargetLocation = SelectedTargetLocation.ToString(), TaskState = TaskStateCode.Task_Running, CreateTime = DateTime.Now, //ReportState = 0 }; //任务校验和添加新任务(区分任务类型) if (SelectedTaskTypeIndex == 0) { taskRT.TaskType = 10; } else if (SelectedTaskTypeIndex == 1) { taskRT.TaskType = 11; } else if (SelectedTaskTypeIndex == 2 || SelectedTaskTypeIndex == 3) { taskRT.TaskType = SelectedTaskTypeIndex; } else { MessageBox.Show("任务类型错误!"); return; } Insert(taskRT, taskRT.TaskType); SqlHelper.NewEventLog($"手动下发调度任务:任务号:{taskRT.TaskId}", "USER"); //重载任务表 LoadTaskGrid(); } #endregion /// /// 加载下拉框内容 /// public void LoadColumns() { ColumnList.Clear(); //ColumnList.Add("作业号"); ColumnList.Add("任务号"); //ColumnList.Add("托盘号"); ColumnList.Add("任务类型"); ColumnList.Add("源站点"); ColumnList.Add("目标站点"); ColumnList.Add("任务状态"); //ColumnList.Add("生成时间"); col.Clear(); //col.Add("作业号", "JobId"); col.Add("任务号", "TaskId"); //col.Add("托盘号", "PalletId"); col.Add("任务类型", "TaskType"); col.Add("源站点", "SourceLocation"); col.Add("目标站点", "TargetLocation"); col.Add("任务状态", "TaskState"); //col.Add("生成时间", "CreateTime"); RGVNumbers.Clear(); for (int i = 0; i < RGVStation.RGVCount; i++) { RGVNumbers.Add(i); } } /// /// 加载表格内容 /// public void LoadTaskGrid() { using var context = new AppDbContext(); var tasks = context.Set() .OrderByDescending(t => t.CreateTime) .ToList(); TaskRT.Clear(); //遍历表中每行数据并初始化值 foreach (TaskRT task in tasks) { TaskRT.Add(task); } } /// /// 向调度表中插入任务 /// /// TaskRT类的实例化对象 /// 任务类型 /// public void Insert(TaskRT taskRT, int taskType) { try { using var context = new AppDbContext(); context.Set() .Add(taskRT); int result = context.SaveChanges(); if (result == 1) Log.Warning($"【手动添加调度任务】任务号:{taskRT.TaskId},{JsonConvert.SerializeObject(taskRT)}"); } catch (DbUpdateException e) { MessageBox.Show($"发生了预期之外的错误:{e.Message}(错误代码:TVM000002)"); } LoadTaskGrid(); } /// /// 站点信息初始化 /// void LocationInitialize() { //Rows = new List(); //Columns = new List(); //Floors = new List(); //RowCount = int.Parse(ConfigurationManager.AppSettings["Row"]); //for (int i = 1; i <= RowCount; i++) //{ // Rows.Add(i); //} //ColumnCount = int.Parse(ConfigurationManager.AppSettings["Column"]); //for (int i = 1; i <= ColumnCount; i++) //{ // Columns.Add(i); //} //FloorCount = int.Parse(ConfigurationManager.AppSettings["Floor"]); //for (int i = 1; i <= FloorCount; i++) //{ // Floors.Add(i); //} SourceLocations.Clear(); foreach (var item in CircleRGVsViewModel.route) { SourceLocations.Add(item.Key); } } /// /// 取货站点对应放货站点 /// [RelayCommand] void SourceToTarget() { try { SelectedTargetLocation = CircleRGVsViewModel.route[SelectedSourceLocation]; } catch { } } /// /// 下发测试任务 /// [RelayCommand] void SendRGVTest() { if (MessageBox.Show("此操作会向环穿地面站PLC直接写入命令!是否继续?","",MessageBoxButton.YesNo) != MessageBoxResult.OK) { return; } CircleRGVStationCommand circleRGVStationCommand = new CircleRGVStationCommand() { Write_DeviceNumber = SelectedRGVNumber, Write_TaskNumber = SqlHelper.GetTaskIdByManualGeneration(), Write_TaskType = TestingTaskTypeIndex + 1, Write_SourceLocation = SelectedSourceLocation, Write_TargetLocation = SelectedTargetLocation, }; CircleRGVsViewModel.SendRGVStationCommand(circleRGVStationCommand); Log.Information($"【环穿下发任务测试】直接向地面站PLC下发任务:{JsonConvert.SerializeObject(circleRGVStationCommand)}"); SqlHelper.NewEventLog($"向地面站PLC直接写入测试任务:任务号:{circleRGVStationCommand.Write_TaskNumber}", "USER"); IsTopDrawerOpen = false; } /// /// 清空选择项 /// [RelayCommand] void TestClear() { SelectedRGVNumber = 0; SelectedSourceLocation = 0; SelectedTargetLocation = 0; } /// /// 新任务输入校验 /// public void InputCheck() { //跨巷道使用 if (string.IsNullOrEmpty(SelectedSourceLocation.ToString().Trim())) { MessageBox.Show("请选择取货站点!"); return; } if (string.IsNullOrEmpty(SelectedTargetLocation.ToString().Trim())) { MessageBox.Show("请选择目标站点!"); return; } } Action action; //[RelayCommand] void TaskFinishHandler() { InputDialog inputDialog = new InputDialog(); inputDialog.ShowDialog(); action = TaskFinish; } void TaskCancelHandler() { InputDialog inputDialog = new InputDialog(); inputDialog.ShowDialog(); action = TaskDelete; } void UpdateTaskStateToReadyHandler() { InputDialog inputDialog = new InputDialog(); inputDialog.ShowDialog(); action = UpdateTaskStateToReady; } /// /// 手动完成任务 /// [RelayCommand] void TaskFinish(string taskId) { using var context = new AppDbContext(); var task = context.Set() .Where(t => t.TaskId == taskId) .FirstOrDefault(); if (task == null) { MessageBox.Show("获取任务号错误!自动移除该任务"); context.Database .ExecuteSqlInterpolated($"DELETE FROM TASK WHERE TASKID={taskId}"); context.SaveChanges(); return; } string taskType = ""; switch (task.TaskType) { case 10: taskType = "实垛"; break; case 11: taskType = "空托"; break; default: break; } if (MessageBox.Show($"确认人工完成任务号:{taskId}的任务?\r\n(错误的操作时机可能会导致生成空任务)", "警告", MessageBoxButton.OKCancel) == MessageBoxResult.OK) { task.TaskState = TaskStateCode.Task_Finish_Manual; if (context.SaveChanges() == 1) { Log.Information($"【人工操作】手动完成任务,任务号:{taskId}"); SqlHelper.NewEventLog($"人工完成{taskType}任务:{taskId}", "USER"); } } LoadTaskGrid(); } /// /// 手动删除(取消)任务 /// [RelayCommand] void TaskDelete(string taskId) { using var context = new AppDbContext(); var task = context.Set() .Where(t => t.TaskId == taskId) .FirstOrDefault(); if (task == null) { MessageBox.Show("获取任务号错误!自动移除该任务"); context.Database .ExecuteSqlInterpolated($"DELETE FROM TASK WHERE TASKID={taskId}"); context.SaveChanges(); return; } string taskType = ""; switch (task.TaskType) { case 10: taskType = "实垛"; break; case 11: taskType = "空托"; break; default: break; } if (MessageBox.Show($"确认人工取消任务号:{taskId}的任务?\r\n(错误的操作时机可能会导致生成空任务)", "警告", MessageBoxButton.OKCancel) == MessageBoxResult.OK) { task.TaskState = TaskStateCode.Task_Finish_Cancel; if (context.SaveChanges() == 1) { Log.Information($"【人工操作】手动取消任务,任务号:{taskId}"); SqlHelper.NewEventLog($"人工取消{taskType}任务:{taskId}", "USER"); } } LoadTaskGrid(); } /// /// 当向环穿下发任务失败时,可以选择重新下发 /// 只能在调度状态为【环穿-待执行】时可用 /// /// [RelayCommand] void UpdateTaskStateToReady(string taskId) { using var context = new AppDbContext(); var task = context.Set() .Where(t => t.TaskId == taskId && t.ScheduleState== ScheduleStateCode.Trans_CircleRGV_Ready) .FirstOrDefault(); if (task == null) { MessageBox.Show("设备运行时的任务无法重下!"); return; } if (MessageBox.Show($"确认将任务:{taskId}的任务状态更改为【待执行】?\r\n此操作会重新下发当前任务(仅在环穿调度状态为【环穿-待执行】时生效)", "警告", MessageBoxButton.OKCancel) == MessageBoxResult.OK) { task.TaskState= TaskStateCode.Task_Ready; if (context.SaveChanges() == 1) { Log.Information($"【人工操作】重新下发任务,任务号:{taskId}"); SqlHelper.NewEventLog($"人工重下任务:{taskId}", "USER"); } } LoadTaskGrid(); } } }