Files
FT479/WPFWCSDemo/ViewModels/TaskViewModel.cs
2026-06-29 14:46:32 +08:00

764 lines
20 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
{
/// <summary>
/// 用于实时更新任务表的定时器
/// </summary>
private DispatcherTimer dispatcherTimer;
public TaskViewModel()
{
TaskRT = new ObservableCollection<TaskRT>();
ColumnList = new List<string>();
col = new Dictionary<string, string>();
SourceLocations = new List<int>();
TargetLocations = new List<int>();
RGVNumbers = new List<int>();
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();
}
}
/// <summary>
/// 是否更新任务表的标志
/// </summary>
bool b;
/// <summary>
/// 调度任务字段---原数据/视图数据
/// </summary>
[ObservableProperty]
ObservableCollection<TaskRT> _taskRT;
/// <summary>
/// 搜索关键字
/// </summary>
[ObservableProperty]
string? _keywords;
/// <summary>
/// 筛选列表集合
/// </summary>
[ObservableProperty]
List<string> _columnList;
/// <summary>
/// 筛选列表集合对应的查询字段
/// </summary>
Dictionary<string, string> col;
/// <summary>
/// 筛选列表文本
/// </summary>
[ObservableProperty]
string? _columnName;
/// <summary>
/// 筛选列表文本选择项
/// </summary>
[ObservableProperty]
string? _columnNameSelected;
/// <summary>
/// 筛选列表选项
/// </summary>
[ObservableProperty]
int _taskTypeSelectedIndex;
/// <summary>
/// 右侧对话框弹出属性
/// </summary>
[ObservableProperty]
bool _isRightDrawerOpen;
/// <summary>
/// 顶部对话框弹出属性
/// </summary>
[ObservableProperty]
bool _isTopDrawerOpen;
/// <summary>
/// 站点初始化集合
/// </summary>
[ObservableProperty]
int _rowCount;
[ObservableProperty]
int _columnCount;
[ObservableProperty]
int _floorCount;
[ObservableProperty]
List<int> _rows;
[ObservableProperty]
List<int> _columns;
[ObservableProperty]
List<int> _floors;
/// <summary>
/// 取放货站点集合
/// </summary>
[ObservableProperty]
List<int> _sourceLocations;
[ObservableProperty]
List<int> _targetLocations;
/// <summary>
/// 测试下发界面任务类型
/// </summary>
[ObservableProperty]
int _testingTaskTypeIndex;
/// <summary>
/// 任务类型
/// </summary>
[ObservableProperty]
int _selectedTaskTypeIndex;
/// <summary>
/// 输入托盘号
/// </summary>
[ObservableProperty]
string _inputTaskId;
/// <summary>
/// 取货站点
/// </summary>
[ObservableProperty]
int _selectedSourceLocation;
/// <summary>
/// 放货站点
/// </summary>
[ObservableProperty]
int _selectedTargetLocation;
/// <summary>
/// 小车编号集合
/// </summary>
[ObservableProperty]
List<int> _rGVNumbers;
/// <summary>
/// 选中小车编号
/// </summary>
[ObservableProperty]
int _selectedRGVNumber;
/// <summary>
/// 右侧对话框弹出命令
/// </summary>
[RelayCommand]
private void NewTask()
{
IsRightDrawerOpen = true;
}
/// <summary>
/// 顶部对话框弹出命令---堆垛机测试
/// </summary>
[RelayCommand]
private void StackerTesting()
{
IsTopDrawerOpen = true;
}
/// <summary>
/// 更改任务类型选项直接更新表
/// </summary>
//[RelayCommand]
void TaskTypeSelectItemChanged()
{
using var context = new AppDbContext();
List<TaskRT> tasks;
if (TaskTypeSelectedIndex == 1)
{
tasks = context.Set<TaskRT>()
.OrderByDescending(t => t.CreateTime)
.Where(t => t.TaskType == 10)
.ToList();
}
else if (TaskTypeSelectedIndex == 2)
{
tasks = context.Set<TaskRT>()
.OrderByDescending(t => t.CreateTime)
.Where(t => t.TaskType == 11)
.ToList();
}
else
{
tasks = context.Set<TaskRT>()
.OrderByDescending(t => t.CreateTime)
.ToList();
}
TaskRT.Clear();
//遍历表中每行数据并初始化值
foreach (TaskRT task in tasks)
{
TaskRT.Add(task);
}
}
/// <summary>
/// 查询任务
/// </summary>
[RelayCommand]
public void Query()
{
//关键词不为空且列名不为空
if (!string.IsNullOrEmpty(Keywords) && !string.IsNullOrEmpty(ColumnName))
{
using var context = new AppDbContext();
var tasks=context.Set<TaskRT>()
.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;
}
/// <summary>
/// 重置筛选项
/// </summary>
[RelayCommand]
void Clear()
{
Keywords = string.Empty;
ColumnName = string.Empty;
LoadTaskGrid();
b = true;
}
#region 添加新任务相关
// 下拉框获取值属性 (源/目标排、列、层)
/// <summary>
/// 点击新建任务按钮命令
/// </summary>
[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
/// <summary>
/// 加载下拉框内容
/// </summary>
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);
}
}
/// <summary>
/// 加载表格内容
/// </summary>
public void LoadTaskGrid()
{
using var context = new AppDbContext();
var tasks = context.Set<TaskRT>()
.OrderByDescending(t => t.CreateTime)
.ToList();
TaskRT.Clear();
//遍历表中每行数据并初始化值
foreach (TaskRT task in tasks)
{
TaskRT.Add(task);
}
}
/// <summary>
/// 向调度表中插入任务
/// </summary>
/// <param name="TaskRT">TaskRT类的实例化对象</param>
/// <param name="taskType">任务类型</param>
/// <returns></returns>
public void Insert(TaskRT taskRT, int taskType)
{
try
{
using var context = new AppDbContext();
context.Set<TaskRT>()
.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();
}
/// <summary>
/// 站点信息初始化
/// </summary>
void LocationInitialize()
{
//Rows = new List<int>();
//Columns = new List<int>();
//Floors = new List<int>();
//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);
}
}
/// <summary>
/// 取货站点对应放货站点
/// </summary>
[RelayCommand]
void SourceToTarget()
{
try
{
SelectedTargetLocation = CircleRGVsViewModel.route[SelectedSourceLocation];
}
catch
{
}
}
/// <summary>
/// 下发测试任务
/// </summary>
[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;
}
/// <summary>
/// 清空选择项
/// </summary>
[RelayCommand]
void TestClear()
{
SelectedRGVNumber = 0;
SelectedSourceLocation = 0;
SelectedTargetLocation = 0;
}
/// <summary>
/// 新任务输入校验
/// </summary>
public void InputCheck()
{
//跨巷道使用
if (string.IsNullOrEmpty(SelectedSourceLocation.ToString().Trim()))
{
MessageBox.Show("请选择取货站点!");
return;
}
if (string.IsNullOrEmpty(SelectedTargetLocation.ToString().Trim()))
{
MessageBox.Show("请选择目标站点!");
return;
}
}
Action<string> 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;
}
/// <summary>
/// 手动完成任务
/// </summary>
[RelayCommand]
void TaskFinish(string taskId)
{
using var context = new AppDbContext();
var task = context.Set<TaskRT>()
.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();
}
/// <summary>
/// 手动删除(取消)任务
/// </summary>
[RelayCommand]
void TaskDelete(string taskId)
{
using var context = new AppDbContext();
var task = context.Set<TaskRT>()
.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();
}
/// <summary>
/// 当向环穿下发任务失败时,可以选择重新下发
/// 只能在调度状态为【环穿-待执行】时可用
/// </summary>
/// <param name="taskId"></param>
[RelayCommand]
void UpdateTaskStateToReady(string taskId)
{
using var context = new AppDbContext();
var task = context.Set<TaskRT>()
.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();
}
}
}