using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using HH.WCS.Mobox3.RiDong.dispatch;
|
using HH.WCS.Mobox3.RiDong.dto;
|
using HH.WCS.Mobox3.RiDong.models;
|
using HH.WCS.Mobox3.RiDong.util;
|
using HH.WCS.Mobox3.RiDong.wms;
|
|
namespace HH.WCS.Mobox3.RiDong.generalMethod;
|
|
/// <summary>
|
/// 任务帮助类
|
/// </summary>
|
public static class TaskHelper
|
{
|
/// <summary>
|
/// 根据作业创建对应任务
|
/// </summary>
|
/// <param name="operation">作业模型</param>
|
public static void CreateTask(Operation operation)
|
{
|
// 根据任务类型创建不同的任务
|
switch (operation.N_TYPE)
|
{
|
case 1:
|
case 2:
|
case 3:
|
case 4:
|
case 5:
|
case 7:
|
CreateTwoTask(operation);
|
break;
|
case 6:
|
CreateOneTask(operation);
|
break;
|
}
|
}
|
|
/// <summary>
|
/// 创建一条任务
|
/// </summary>
|
/// <param name="operation"></param>
|
private static void CreateOneTask(Operation operation)
|
{
|
var tasks = new List<Task>();
|
|
// 任务1
|
var task1 = new Task()
|
{
|
// 作业编码
|
S_OP_CODE = operation.S_CODE,
|
// 任务号
|
S_CODE = HelperMethod.GenerateTaskNo("任务号", "TA"),
|
// 任务类型
|
N_TYPE = operation.N_TYPE,
|
// 任务类型
|
S_TYPE = Task.GetStateType(operation.N_TYPE),
|
// 起点货位
|
S_START_LOC = operation.S_START_LOC,
|
// 起点库区
|
S_START_AREA = operation.S_START_AREA,
|
// 终点货位
|
S_END_LOC = operation.S_END_LOC,
|
// 终点库区
|
S_END_AREA = operation.S_END_AREA,
|
// 设备类型
|
N_SCHEDULE_TYPE = 2,
|
// 设备类型
|
S_SCHEDULE_TYPE = "agv",
|
// 容器编码
|
S_CNTR_CODE = operation.S_CNTR_CODE,
|
// 配盘单号
|
S_DC_NO = operation.S_DC_NO,
|
// 作业类型
|
S_OP_NAME = operation.S_OP_DEF_NAME,
|
};
|
|
tasks.Add(task1);
|
|
var querySqlSugarClient = AdoSqlMethod<object>.QuerySqlSugarClient();
|
|
try
|
{
|
// 修改作业状态为执行中
|
operation.N_B_STATE = 1;
|
operation.S_B_STATE = "执行";
|
operation.T_START_TIME = DateTime.Now;
|
|
AdoSqlMethod<Task>.AddListTran(querySqlSugarClient, tasks);
|
AdoSqlMethod<Operation>.UpdateFirstTran(querySqlSugarClient, operation,
|
p => new { p.N_B_STATE, p.S_B_STATE, p.T_START_TIME });
|
}
|
catch (Exception e)
|
{
|
Console.WriteLine(e);
|
throw;
|
}
|
}
|
|
/// <summary>
|
/// 创建两条任务
|
/// </summary>
|
/// <returns></returns>
|
/// <param name="operation">作业模型</param>
|
private static void CreateTwoTask(Operation operation)
|
{
|
var tasks = new List<Task>();
|
|
// 任务1
|
var task1 = new Task()
|
{
|
// 作业编码
|
S_OP_CODE = operation.S_CODE,
|
// 任务号
|
S_CODE = HelperMethod.GenerateTaskNo("任务号", "TA"),
|
// 任务类型
|
N_TYPE = operation.N_TYPE,
|
// 任务类型
|
S_TYPE = Task.GetStateType(operation.N_TYPE),
|
// 起点货位
|
S_START_LOC = operation.S_START_LOC,
|
// 起点库区
|
S_START_AREA = operation.S_START_AREA,
|
// 终点货位
|
S_END_LOC = operation.S_EXT_ATTR1,
|
// 终点库区
|
S_END_AREA = Operation.GetArea(operation.S_EXT_ATTR1),
|
// 设备类型
|
N_SCHEDULE_TYPE = Task.GetScheduleTypetoInt(operation.N_TYPE, 1),
|
// 设备类型
|
S_SCHEDULE_TYPE = Task.GetScheduleTypetoStr(operation.N_TYPE, 1),
|
// 容器编码
|
S_CNTR_CODE = operation.S_CNTR_CODE,
|
// 任务名称
|
S_OP_NAME = operation.S_OP_DEF_NAME,
|
// 配盘单号
|
S_DC_NO = operation.S_DC_NO,
|
// 任务名称
|
};
|
|
tasks.Add(task1);
|
|
// 任务2
|
var task2 = new Task()
|
{
|
// 作业编码
|
S_OP_CODE = operation.S_CODE,
|
// 任务号
|
S_CODE = HelperMethod.GenerateTaskNo("任务号", "TA"),
|
// 任务类型
|
N_TYPE = operation.N_TYPE,
|
// 任务类型
|
S_TYPE = Task.GetStateType(operation.N_TYPE),
|
// 起点货位
|
S_START_LOC = operation.S_EXT_ATTR1,
|
// 起点库区
|
S_START_AREA = Operation.GetArea(operation.S_EXT_ATTR1),
|
// 终点货位
|
S_END_LOC = operation.S_END_LOC,
|
// 终点库区
|
S_END_AREA = operation.S_END_AREA,
|
// 设备类型
|
N_SCHEDULE_TYPE = Task.GetScheduleTypetoInt(operation.N_TYPE, 2),
|
// 设备类型
|
S_SCHEDULE_TYPE = Task.GetScheduleTypetoStr(operation.N_TYPE, 2),
|
// 容器编码
|
S_CNTR_CODE = operation.S_CNTR_CODE,
|
// 任务名称
|
S_OP_NAME = operation.S_OP_DEF_NAME,
|
// 配盘单号
|
S_DC_NO = operation.S_DC_NO
|
};
|
|
tasks.Add(task2);
|
|
// 修改作业状态为执行中
|
operation.N_B_STATE = 1;
|
operation.S_B_STATE = "执行";
|
operation.T_START_TIME = DateTime.Now;
|
|
var querySqlSugarClient = AdoSqlMethod<object>.QuerySqlSugarClient();
|
|
try
|
{
|
querySqlSugarClient.BeginTran();
|
AdoSqlMethod<Task>.AddListTran(querySqlSugarClient, tasks);
|
AdoSqlMethod<Operation>.UpdateFirstTran(querySqlSugarClient, operation,
|
p => new { p.N_B_STATE, p.S_B_STATE, p.T_START_TIME });
|
|
querySqlSugarClient.CommitTran();
|
}
|
catch (Exception e)
|
{
|
if (operation.N_TYPE == 1)
|
{
|
LogHelper.Info($"作业号为:{operation.S_CODE}的任务创建失败", "出入库流程记录");
|
}
|
else
|
{
|
LogHelper.Info($"作业号为:{operation.S_CODE}的任务创建失败", "出入库流程记录");
|
}
|
querySqlSugarClient.RollbackTran();
|
}
|
}
|
|
/// <summary>
|
/// 任务推送(输送线)以及判断输送线任务是否完成
|
/// </summary>
|
/// <param name="task"></param>
|
/// <returns></returns>
|
public static void InterceptFromPLC(Task task)
|
{
|
|
UpdateTask(task);
|
|
// ConveyorLinesInfos conveyorLinesInfos = new ConveyorLinesInfos();
|
// int price = 0;
|
//
|
// // 等待状态,说明没有推送,判断起点输送线是否是对应的条形码,如果是,推送,如果不是,跳过
|
// if (task.N_B_STATE == 0)
|
// {
|
// // 获取该货位所代表的线体信息
|
// conveyorLinesInfos = AdoSqlMethod<ConveyorLinesInfos>.QueryFirst(p => p.S_LOCATION == task.S_START_LOC);
|
// price = 6666;
|
// }
|
// else if (task.N_B_STATE == 2)
|
// {
|
// // 如果已经为执行中了,就说明起点已经推送了,此时找终点
|
// // 获取该货位所代表的线体信息
|
// conveyorLinesInfos = AdoSqlMethod<ConveyorLinesInfos>.QueryFirst(p => p.S_LOCATION == task.S_END_LOC);
|
// price = 1;
|
// }
|
//
|
// if (conveyorLinesInfos != null)
|
// {
|
// // 如果包含
|
// if (!string.IsNullOrEmpty(conveyorLinesInfos.S_IP) && MitsubishiHelper.plcDic.Keys.Contains(conveyorLinesInfos.S_IP))
|
// {
|
// // 获取指定数据
|
// var device = MitsubishiHelper.getDevice(conveyorLinesInfos.S_IP, conveyorLinesInfos.S_CODE);
|
//
|
// // if()
|
//
|
// // 判断是否一致,一致的情况下给输送线写完成指令
|
// MitsubishiHelper.setDevice(conveyorLinesInfos.S_IP, conveyorLinesInfos.S_CODE, price);
|
//
|
// if (UpdateTask(task))
|
// {
|
// if (task.N_TYPE == 1)
|
// {
|
// LogHelper.Info($"任务编号为:{task.S_CODE}任务状态修改成功","出入库流程记录");
|
// }
|
// else if (task.N_TYPE == 2 || task.N_TYPE == 3)
|
// {
|
// LogHelper.Info($"任务编号为:{task.S_CODE}任务状态修改成功","出入库流程记录");
|
// }
|
// }
|
// else
|
// {
|
// if (task.N_TYPE == 1)
|
// {
|
// LogHelper.Info($"任务编号为:{task.S_CODE}任务状态修改失败","出入库流程记录");
|
// }
|
// else if (task.N_TYPE == 2 || task.N_TYPE == 3)
|
// {
|
// LogHelper.Info($"任务编号为:{task.S_CODE}任务状态修改失败","出入库流程记录");
|
// }
|
// }
|
// }
|
// }
|
}
|
|
/// <summary>
|
/// agv任务推送
|
/// </summary>
|
/// <param name="task"></param>
|
public static bool SendTaskFromAGV(Task task)
|
{
|
var start = "0"; var end = "0";
|
|
var result = false;
|
|
if (task.N_B_STATE == 0)
|
{
|
if (task.S_SCHEDULE_TYPE == "agv")
|
{
|
start = LocationHelper.GetAgvSite(task.S_START_LOC);
|
end = LocationHelper.GetAgvSite(task.S_END_LOC);
|
|
var dic = new Dictionary<string, string>();
|
dic.Add("IKey", task.S_CODE);
|
dic.Add("From", start);
|
dic.Add("To", end);
|
dic.Add("Func", 0.ToString());
|
dic.Add("Data", 0.ToString());
|
|
// 判断任务的类型决定巷道的编号
|
if (task.N_TYPE == 1 || task.N_TYPE == 3)
|
{
|
var location = AdoSqlMethod<Location>.QueryFirst(p => p.S_CODE == task.S_END_LOC);
|
var roadwayCorrespondingNo = Settings.RoadwayCorrespondingNos.First(p => p.roadway == location.N_ROADWAY);
|
dic.Add("Ctype", roadwayCorrespondingNo.no.ToString());
|
}
|
else if (task.N_TYPE == 2 || task.N_TYPE == 4 || task.N_TYPE == 5 || task.N_TYPE == 6 || task.N_TYPE == 7)
|
{
|
var location = AdoSqlMethod<Location>.QueryFirst(p => p.S_CODE == task.S_START_LOC);
|
var roadwayCorrespondingNo = Settings.RoadwayCorrespondingNos.First(p => p.roadway == location.N_ROADWAY);
|
dic.Add("Ctype", roadwayCorrespondingNo.no.ToString());
|
}
|
|
// dic.Add("Ctrl", 1.ToString());
|
|
// 创建任务
|
var res = NDC.AddNewOrderNew(1, task.N_PRIORITY, task.S_CODE, dic);
|
|
if (res != null)
|
{
|
result = true;
|
LogHelper.Info($"AGV推送任务成功{dic},数据库修改成功", "出入库流程记录");
|
}
|
}
|
}
|
|
return result;
|
}
|
|
/// <summary>
|
/// 推送小车充电任务
|
/// </summary>
|
/// <param name="lockNo"></param>
|
public static void Traffic(string lockNo)
|
{
|
var dic = new Dictionary<string, string>();
|
dic.Add("Unit", 1.ToString());
|
dic.Add("Door", lockNo);
|
NDC.StartNewOrderWithQCmd(164, DateTime.Now.Ticks.ToString(), dic);
|
}
|
|
/// <summary>
|
/// 修改任务状态
|
/// </summary>
|
/// <param name="task"></param>
|
/// <returns>是否更新成功</returns>
|
public static bool UpdateTask(Task task)
|
{
|
bool result = false;
|
DateTime now = DateTime.Now;
|
|
switch (task.N_B_STATE)
|
{
|
// 初始状态到执行中
|
case 0:
|
task.N_B_STATE = 2;
|
task.S_B_STATE = "执行中";
|
task.T_MODIFY = now;
|
task.T_START_TIME = now;
|
result = AdoSqlMethod<Task>.UpdateFirst(task, p => new { p.N_B_STATE, p.S_B_STATE, p.T_MODIFY, p.T_START_TIME });
|
break;
|
// 执行中到完成
|
case 2:
|
task.N_B_STATE = 3;
|
task.S_B_STATE = "完成";
|
task.T_MODIFY = now;
|
task.T_END_TIME = now;
|
result = AdoSqlMethod<Task>.UpdateFirst(task, p => new { p.N_B_STATE, p.S_B_STATE, p.T_MODIFY, p.T_END_TIME });
|
break;
|
// 可以添加更多状态转换逻辑
|
default:
|
// 未知状态,可能记录日志或抛出异常
|
break;
|
}
|
|
return result;
|
}
|
|
/// <summary>
|
/// 根据配盘单创建出库任务
|
/// </summary>
|
/// <param name="models"></param>
|
public static void CreateOutTaskFromDistributionCntrDetail(List<TN_Distribution_CNTR> models)
|
{
|
var sqlSugarClient = AdoSqlMethod<object>.QuerySqlSugarClient();
|
|
foreach (var model in models)
|
{
|
var outbound = AdoSqlMethod<OutboundOrder>.QueryFirst(p => p.S_NO == model.S_BS_NO);
|
|
|
var operationDto = new OperationDto()
|
{
|
cntrCode = model.S_CNTR_CODE,
|
startLocation = model.S_LOC_CODE,
|
taskType = model.N_OUT_TYPE,
|
odd = model.S_DC_NO,
|
};
|
|
// 查询可用终点出库货位
|
var queryRandomLocationFromSite = LocationMethod.QueryLocation(operationDto);
|
|
// 出库接驳位有可用的,此时才可以创建任务
|
if (queryRandomLocationFromSite != null)
|
{
|
// 创建作业
|
// 查询作业表
|
var oldoperation =
|
AdoSqlMethod<Operation>.QueryFirst(op => op.S_CNTR_CODE == model.S_CNTR_CODE && op.N_B_STATE < 2);
|
|
if (oldoperation == null)
|
{
|
var newoperation = new Operation()
|
{
|
S_CODE = HelperMethod.GenerateTaskNo("作业号", "OP"),
|
N_TYPE = model.N_OUT_TYPE,
|
S_TYPE = Operation.GetTypeStr(model.N_OUT_TYPE),
|
S_START_LOC = model.S_LOC_CODE,
|
S_START_AREA = Operation.GetArea(model.S_LOC_CODE),
|
S_EXT_ATTR1 = queryRandomLocationFromSite.S_CODE,
|
S_END_LOC = model.N_OUT_TYPE == 2 ? "CKK-1" : "JJCKK-1",
|
// 终点库区编码
|
S_END_AREA = Operation.GetArea(model.N_OUT_TYPE == 2 ? "CKK-1" : "JJCKK-1"),
|
S_CNTR_CODE = model.S_CNTR_CODE,
|
S_DC_NO = model.S_DC_NO,
|
S_OUT_TARGET = outbound.S_OUT_TARGET
|
};
|
|
// 根据托盘号查询是否整托或分拣
|
var cntrItemDetails = AdoSqlMethod<CntrItemDetail>.QueryList(p => p.S_CNTR_CODE == newoperation.S_CNTR_CODE);
|
|
var tnDistributionCntrDetails = AdoSqlMethod<TN_Distribution_CNTR_Detail>.QueryList(p => p.S_DC_NO == model.S_DC_NO);
|
|
if (cntrItemDetails.Count > 0 && tnDistributionCntrDetails.Count > 0)
|
{
|
float num1 = 0;
|
|
foreach (var cntrItem in cntrItemDetails)
|
{
|
num1 += cntrItem.F_QTY;
|
}
|
|
float num2 = 0;
|
|
foreach (var tnDistributionCntrDetail in tnDistributionCntrDetails)
|
{
|
num2 += tnDistributionCntrDetail.F_QTY;
|
}
|
|
// 容器明细数量大于配盘数
|
if (num1 > num2)
|
{
|
newoperation.S_OP_DEF_NAME = "分拣出库";
|
}
|
else
|
{
|
// 容器数小于配盘数量
|
newoperation.S_OP_DEF_NAME = "整托出库";
|
}
|
}
|
else
|
{
|
LogHelper.Info($"配盘{model.S_DC_NO}的配盘明细不存在或托盘{model.S_CNTR_CODE}的容器货品明细不存在");
|
}
|
|
try
|
{
|
sqlSugarClient.BeginTran();
|
|
// 任务创建成功的情况下,修改出库单状态值
|
if (AdoSqlMethod<Operation>.AddFirstTran(sqlSugarClient, newoperation))
|
{
|
model.N_B_STATE = 2;
|
model.S_B_STATE = "出库作业已创建";
|
|
AdoSqlMethod<TN_Distribution_CNTR>.UpdateFirstTran(sqlSugarClient, model,
|
p => new { p.N_B_STATE, p.S_B_STATE });
|
|
var container = AdoSqlMethod<Container>.QueryFirst(p => p.S_CODE == model.S_CNTR_CODE);
|
|
container.C_ENABLE = 'N';
|
AdoSqlMethod<Container>.UpdateFirst(container, p => new { p.C_ENABLE });
|
|
// 给起点货位加锁
|
LocationHelper.LockLoc(newoperation.S_START_LOC, 2);
|
}
|
|
sqlSugarClient.CommitTran();
|
}
|
catch (Exception e)
|
{
|
sqlSugarClient.RollbackTran();
|
Console.WriteLine(e);
|
throw;
|
}
|
}
|
}
|
}
|
}
|
}
|