using Admin.NET.Core.Service;
using Furion.DatabaseAccessor;
using Furion.Logging;
using WCS.Application.Entity;
using WCS.Application.Util;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.ComponentTCBBatchCreateContainerServiceVersionRequest.Types;
namespace WCS.Application;
///
/// 示例开放接口
///
[ApiDescriptionSettings("开放接口", Name = "OpenApi", Order = 100)]
//[Authorize(AuthenticationSchemes = SignatureAuthenticationDefaults.AuthenticationScheme)]
[AllowAnonymous]
public class OpenApi : IDynamicApiController
{
private static readonly ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId);
private readonly UserManager _userManager;
private readonly SysCacheService _sysCacheService;
private readonly SysConfigService _sysConfigService;
private readonly WcsTaskService _taskService;
public OpenApi(UserManager userManager, SysCacheService sysCacheService, SysConfigService sysConfigService, WcsTaskService taskService)
{
_userManager = userManager;
_sysCacheService = sysCacheService;
_sysConfigService = sysConfigService;
_taskService = taskService;
}
///
/// 测试分配任务路径
///
/// 任务信息
/// 反馈信息
[AllowAnonymous]
public async Task AddAssignTasks(AgvTaskSend models)
{
var response = await new HttpService().GenAgvSendTask(models);
//var response2 = await new HttpService().GenAgvContinueTask("Tk20250503000001");
//var response3 = await new HttpService().GenAgvUnbind("models", "B010101");
return response;
// 验证任务是否已存在
//var taskInfo = await _db.Queryable().FirstAsync(w => w.TaskNo == models.TaskNo);
//if (taskInfo == null)
//{
// throw Oops.Bah("任务:" + models.TaskNo + ";不存在!");
//}
//var data1 = FourWayCarUtil.GetCarPath("091501", "091601","0");
//if (data1 == null) //|| data1.Count == 0
//{
// throw Oops.Bah("分配路径不存在!");
//}
//// 根据任务状态 补充起始结束节点状态
//var data2 = FourWayCarUtil.GetCarPathUp(data1, 0);
//var path = "";
//var executionPath1 = "";
//foreach (var item in data1)
//{
// //路径节点
// var pathXYZ = item.X.ToString().PadLeft(2, '0') + item.Y.ToString().PadLeft(2, '0') + item.Z.ToString().PadLeft(2, '0') + item.NodeCom.ToString();
// path += pathXYZ + ";";
// if (item.IsSendPlc)
// {
// executionPath1 += pathXYZ + ";";
// }
//}
//// 插入四向车任务表
//var carTask1 = new WcsCarTasks()
//{
// TaskNo = taskInfo.TaskNo,
// PreId = "",
// ExecutionPath = executionPath1,
// Path = path,
// CarNo = "",
// Status = TaskStatusEnum.Wait
//};
//var i = _db.Insertable(carTask1).ExecuteCommand();
//Console.WriteLine(""+i);
}
/// WCS接受WMS下发的任务(多
/// 条任务)
/// 任务信息
/// 反馈信息
///
[AllowAnonymous]
[UnitOfWork]
public async Task AddWcsTasks(List modelList)
{
var listTaskNo = modelList.Select(s => s.TaskNo).ToList();
// 验证任务是否已存在
var taskInfo = await _db.Queryable().CountAsync(w => listTaskNo.Contains(w.TaskNo));
if (taskInfo > 0)
{
throw Oops.Bah("任务已存在!");
}
var listTask = new List();
var list = modelList.OrderBy(m => m.Order).ThenBy(m => m.TaskNo).ToList();
foreach (var models in list)
{
if (models.TaskType == "0")
{
models.Order = 1;
}
else
{
models.Order = 2;
}
//新增任务
var taskAdd = new WcsTask()
{
TaskNo = models.TaskNo,
TaskType = (TaskTypeEnum)Convert.ToInt32(models.TaskType),
Type = models.Type,
Status = TaskStatusEnum.Wait,
Levels = 999,
Origin = "WMS",
SkuNo = models.SkuNo,
SkuName=models.SkuName,
LotNo=models.LotNo,
StartRoadway = models.StartRoadway,
StartLocate = models.StartLocate,
EndLocate = models.EndLocate,
EndRoadway = models.EndRoadway,
PalletNo = models.PalletNo,
CreateTime = DateTime.Now
};
// 若非AGV任务增加任务ID
if (models.Type != PLCTypeEnum.AGV)
{
taskAdd.TaskId = FourWayCarUtil.GetTaskId();
}
await _db.Insertable(taskAdd).ExecuteCommandAsync();
}
}
///
/// WCS接受WMS下发的任务(单条任务)
///
/// 任务信息
/// 反馈信息
[AllowAnonymous]
public async Task AddWcsTask(ResponseTasksModel models)
{
// 验证任务是否已存在
var taskInfo = await _db.Queryable().FirstAsync(w => w.TaskNo == models.TaskNo);
if (taskInfo != null)
{
throw Oops.Bah("任务:" + models.TaskNo + ";已存在!");
}
if (models.TaskType == "0")
{
models.Order = 1;
}
else
{
models.Order = 2;
}
//新增任务
var taskAdd = new WcsTask()
{
TaskNo = models.TaskNo,
TaskType = (TaskTypeEnum?)int.Parse(models.TaskType),
Status = TaskStatusEnum.Wait,
Type = models.Type,
Levels = 999,
Origin = "WMS",
SkuNo = models.SkuNo,
SkuName = models.SkuName,
LotNo = models.LotNo,
StartRoadway = models.StartRoadway,
StartLocate = models.StartLocate,
EndLocate = models.EndLocate,
EndRoadway = models.EndRoadway,
PalletNo = models.PalletNo,
};
// 若非AGV任务增加任务ID
if (models.Type != PLCTypeEnum.AGV)
{
taskAdd.TaskId = FourWayCarUtil.GetTaskId();
}
await _db.Insertable(taskAdd).ExecuteCommandAsync();
}
///
/// WCS接收WMS下发的入库单任务
///
///
///
[HttpPost]
[AllowAnonymous]
public async Task AddOrderTask(List models)
{
foreach (var item in models)
{
// 验证任务是否已存在
//var taskInfo = _db.Queryable().First(w => w.OrderNo == item.OrderNo && w.SkuNo == item.SkuNo && w.LotNo == item.LotNo);
//if (taskInfo == null)
//{
var orderAdd = new WcsOderTask()
{
OrderNo = item.OrderNo,
TaskNo = "",
LotNo = item.LotNo,
SkuNo = item.SkuNo,
SkuName = item.SkuName,
BoxType = item.BoxType,
Qty = item.Qty,
TaskType = (TaskTypeEnum)item.TaskType,
};
await _db.Insertable(orderAdd).ExecuteCommandAsync();
//}
}
}
///
/// WCS接收赋码系统推送的箱码信息
///
/// 箱码信息
/// 反馈信息
[HttpPost]
[AllowAnonymous]
public async Task AddBoxInfo(FumaBoxInfoInput models)
{
if (models.Origin != "赋码")
{
throw Oops.Bah("来源未识别");
}
var num = await _db.Queryable().Where(m => m.BoxNo == models.BoxNo).ToListAsync();
var type = "add";
if (num.Count > 0)
{
//WCS存在箱码信息,更新箱码信息(需判断箱码是否已组盘入库)
var num2 = num.Count(m => m.Status != "0" || !string.IsNullOrWhiteSpace(m.PalletNo));
if (num2 > 0)
{
throw Oops.Bah("该箱已入盘入库,不可更新信息");
}
type = "edit";
}
if (models.DelistList.Count == 0)
{
throw Oops.Bah("盒码集合不能为空");
}
var listBox = new List();
foreach (var item in models.DelistList)
{
var level = "3";
if (string.IsNullOrWhiteSpace(item.BoxNo2))
{
level = "2";
}
if (item.DelistList2.Count == 0)
{
throw Oops.Bah("值码集合不能为空");
}
//二级码
foreach (var item2 in item.DelistList2)
{
if (string.IsNullOrWhiteSpace(models.ProductionTime) || string.IsNullOrWhiteSpace(models.ExpirationTime))
{
throw Oops.Bah("生产日期或失效日期不能为空");
}
DateTime proTime;
DateTime expTime;
var isValid = DateTime.TryParse(models.ProductionTime, out proTime);
var isValid2 = DateTime.TryParse(models.ExpirationTime, out expTime);
if (!isValid || !isValid2)
{
throw Oops.Bah("生产日期或失效日期格式错误");
};
var boxAdd = new WcsBoxInfo()
{
BoxNo = models.BoxNo,
//OrderNo = models.OrderNo,
SkuNo = models.SkuNo,
SkuName = models.SkuName,
Standard = models.Standard,
LotNo = models.LotNo,
Qty = item2.Qty,
FullQty = models.FullQty,
//SupplierLot = models.SupplierLot,
InsPectMark = models.InsPectMark,
BitBoxMark = models.BitBoxMark,
//InspectStatus = models.InspectStatus,
ProductionTime = proTime,
ExpirationTime = expTime,
StoreTime = DateTime.Parse(models.StoreTime),
EndLotFlag = string.IsNullOrWhiteSpace(models.EndBatchMark) ? "0" : models.EndBatchMark,
BoxNo2 = item.BoxNo2,
BoxNo3 = item2.BoxNo3,
QtyCount = item2.QtyCount,
QtyOrd = item2.QtyOrd,
Status = "0",
Level = level,
};
listBox.Add(boxAdd);
}
}
await _db.Insertable(listBox).ExecuteCommandAsync();
if (type == "edit")
{
await _db.Deleteable(num).ExecuteCommandAsync();
}
}
///
/// AGV小车申请开门
///
///
///
[HttpPost]
[NonUnify]
public async Task AgvApplyLock(AGVApplyLockInput input)
{
AGVCallBackResponse result = new AGVCallBackResponse()
{
//ReqCode = input.ReqCode,
Message = "成功",
Code = "0"
};
var modPlc = PLCTaskAction.plcs.FirstOrDefault(s => s.Type == PLCTypeEnum.ConveyorLine);
if (modPlc == null)
{
result.Code = "1";
result.Message = "找不到PLC信息";
}
else
{
var modUtil = new PLCUtil(modPlc);
string text = "";
if (input.DeviceIndex == "111")
{
text = "3号卷帘门";
}
else if (input.DeviceIndex == "222")
{
text = "2号卷帘门";
}
else
{
result.Code = "1";
result.Message = "卷帘门编号错误";
return result;
}
var modDevice = await _db.Queryable().FirstAsync(s => s.Text == text);
if (modDevice == null)
{
result.Code = "1";
result.Message = "找不到卷帘门设备信息";
}
else
{
if (input.ActionTask == "applyLock")
{
var (plcResult, value) = modUtil.GetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.PlcPos);
if (plcResult.IsSucceed)
{
//写入10申请开门,等待写入20返回结果让小车通过
plcResult = modUtil.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "10");
if (!plcResult.IsSucceed)
{
result.Code = "1";
result.Message = "打开卷帘门写入值失败";
}
else
{
_sysCacheService.Set("OpenDoor" + input.DeviceIndex, input);
}
}
else
{
result.Code = "1";
result.Message = "获取卷帘门状态失败";
}
}
else
{
var (plcResult, value) = modUtil.GetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.PlcPos);
if (plcResult.IsSucceed && value != 0)
{
plcResult = modUtil.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "30");
if (!plcResult.IsSucceed)
{
result.Code = "1";
result.Message = "关闭卷帘门写入值失败";
}
}
else
{
result.Code = "1";
result.Message = "获取卷帘门状态失败";
}
}
}
}
return result;
}
///
/// AGV小车回调
///
///
///
[HttpPost]
[NonUnify]
[UnitOfWork]
public async Task agvCallback(AGVCallBackInput input)
{
Log.Information("AGV反馈任务" + input.ToJson());
AGVCallBackResponse result = new AGVCallBackResponse()
{
ReqCode = input.ReqCode,
Message = "成功",
Code = "0"
};
if (input.robotTaskCode.Substring(0, 3) != "WCS" && input.robotTaskCode.Substring(0, 2) != "TK")
{
result.Message = "反馈的任务不是WCS的任务";
result.Code = "1";
return result;
}
PLCUtil modUtil = null;
try
{
var modTask = await _db.Queryable().FirstAsync(s => s.TaskNo == input.robotTaskCode);
if (modTask != null)
{
switch (input.Extra.Values.Method)
{
case "end"://任务完成
{
modTask.Status = TaskStatusEnum.Complete;
modTask.FinishDate = DateTime.Now;
await _db.Updateable(modTask).ExecuteCommandAsync();
WcsTaskMonitor modTaskMonitor = new WcsTaskMonitor()
{
TaskNo = modTask.TaskNo,
//PlcId = modDevice.PlcId,
PlcName = "AGV",
StartLocat = modTask.StartLocate,
EndLocat = modTask.EndLocate,
Status = TaskStatusEnum.Complete,
InteractiveMsg = $"AGV小车反馈任务完成",
};
await _db.Insertable(modTaskMonitor).ExecuteCommandAsync();
HubUtil.PublicTask(modTask.Adapt());
HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt());
//反馈WMS任务完成
if (modTask.Origin == "WMS")
{
HttpService httpService = new HttpService();
var inputs = new TaskRequestWMS();
inputs.TaskNo = modTask.TaskNo;
inputs.PalletNo = modTask.PalletNo;
inputs.TaskType = ((int)modTask.TaskType).ToString();
inputs.TaskStatus = "2";
var modResponseTask = httpService.RequestTask(inputs).Result;
}
}
break;
case "outbin"://走出储位
{
WcsTaskMonitor modTaskMonitor = new WcsTaskMonitor()
{
TaskNo = modTask.TaskNo,
//PlcId = modDevice.PlcId,
PlcName = "AGV",
StartLocat = modTask.StartLocate,
EndLocat = modTask.EndLocate,
Status = TaskStatusEnum.Complete,
InteractiveMsg = $"AGV小车反馈任务取货完成,走出储位",
};
await _db.Insertable(modTaskMonitor).ExecuteCommandAsync();
//反馈WMS任务取货完成、WMS判断是平库储位就更新储位状态
if (modTask.Origin == "WMS")
{
HttpService httpService = new HttpService();
var inputs = new TaskRequestWMS();
inputs.TaskNo = modTask.TaskNo;
inputs.PalletNo = modTask.PalletNo;
inputs.TaskType = ((int)modTask.TaskType).ToString();
inputs.TaskStatus = "2";
var modResponseTask = httpService.RequestTaskQh(inputs).Result;
}
}
break;
case "release"://放货申请
{
if (modTask.EndLocate != "B040101")//9号工位地址
{
result.Code = "1";
result.Message = "找不到该任务";
return result;
}
//modTask.Status = TaskStatusEnum.Complete;
modTask.IsComple = "1";
await _db.Updateable(modTask).ExecuteCommandAsync();
WcsTaskMonitor modTaskMonitor = new WcsTaskMonitor()
{
TaskNo = modTask.TaskNo,
//PlcId = modDevice.PlcId,
PlcName = "AGV",
StartLocat = modTask.StartLocate,
EndLocat = modTask.EndLocate,
Status = TaskStatusEnum.Complete,
InteractiveMsg = $"AGV小车反馈任务到达9工位",
};
await _db.Insertable(modTaskMonitor).ExecuteCommandAsync();
HubUtil.PublicTask(modTask.Adapt());
HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt());
if (modTask.Origin == "WMS")
{
HttpService httpService = new HttpService();
var inputs = new TaskRequestWMS();
inputs.TaskNo = modTask.TaskNo;
inputs.PalletNo = modTask.PalletNo;
inputs.TaskType = ((int)modTask.TaskType).ToString();
inputs.TaskStatus = "2";
var modResponseTask = httpService.RequestTaskQh(inputs).Result;
}
}
break;
case "notifyFullSite":
{
var palletNo = input.Extra.Values.carrierCode;
var count = input.Extra.Values.pileCount;
if (string.IsNullOrWhiteSpace(palletNo) || count <= 0)
{
throw new Exception("参数:托盘号/数量验证失败");
}
//向WMS申请空托入库
HttpService httpService = new HttpService();
var inputs = new NullPallInRequest();
inputs.PalletNo = modTask.PalletNo;
inputs.PallNum = count;
inputs.Locate = "B100101";//叠托盘机位置
inputs.HouseNo = "W02";
var modResponseTask = httpService.RequestLiKuPallet(inputs);
}
break;
case "cancel"://任务取消
{
PLCService.AGVStatus = false;
modTask.IsSuccess = TaskSuccessEnum.Fail;
modTask.CancelDate = DateTime.Now;
modTask.Status = TaskStatusEnum.Cancell;
modTask.Levels = 999;
await _db.Updateable(modTask).UpdateColumns(s => new { s.Status, s.IsSuccess, s.FinishDate, s.CancelDate, s.UpdateTime, s.UpdateUserId, s.UpdateUserName }).ExecuteCommandAsync();
//写入任务明细表
WcsTaskMonitor modTaskMonitor = new WcsTaskMonitor()
{
TaskNo = modTask.TaskNo,
PlcId = 0,
PlcName = "",
Status = TaskStatusEnum.Complete,
StartLocat = modTask.StartLocate,
EndLocat = modTask.EndLocate,
InteractiveMsg = "小车通知任务取消",
PalletNo = modTask.PalletNo
};
await _db.Insertable(modTaskMonitor).ExecuteCommandAsync();
HubUtil.PublicTask(modTask.Adapt());
HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt());
}
break;
default:
break;
}
}
else
{
result.Code = "1";
result.Message = "找不到该任务";
}
}
catch (Exception ex)
{
result.Code = "1";
result.Message = ex.Message;
}
finally
{
modUtil?.Close();
}
Log.Information("AGV反馈任务返回" + result.ToJson());
return result;
}
///
/// 获取原材料仓状态
///
///
[HttpPost]
public async Task HuoQuMateralStatus()
{
var data = await _sysConfigService.GetConfigValue("cache_Materal");
return data;
}
///
/// 修改原材料仓状态
///
///
[HttpPost]
public async Task UpdateMateralStatus()
{
await _sysConfigService.UpdateConfigValue("cache_Materal", false);
}
///
/// 获取车间动向
///
///
[HttpPost]
public async Task Workshop()
{
var result = Enum.TryParse(await _sysConfigService.GetConfigValue("workshop_Trend"), out WorkshopEnum workshop);
return workshop;
}
///
/// 修改车间动向
///
///
[HttpPost]
public async Task ChangeWorkshop(RequestTrends input)
{
await _sysConfigService.UpdateConfigValue("workshop_Trend", input.Type.ToString());
}
///
/// 手动入托盘
///
///
//[HttpPost]
//public async Task InPallet(RequestStorage input)
//{
// var intPallet = _sysConfigService.GetConfigValue("cache_Pallet").Result;
// if (intPallet + input.Qty > 3)
// throw Oops.Bah($"输入数量大于可放置数");
// await _sysConfigService.UpdateConfigValue("cache_Pallet", (intPallet + input.Qty).ToString());
//}
///
/// 成品缓存区入库
///
///
///
//[HttpPost]
//[UnitOfWork]
//public async Task ProductStorage(RequestStorage input)
//{
// var intProduct = AGVStorageUtil.ProductCount();
// var intTask = await _db.Queryable().Where(s => s.TaskType == TaskTypeEnum.Move
// && s.Type == PLCTypeEnum.AGV && s.Status <= TaskStatusEnum.Doing
// && s.StartLocate.StartsWith("Z") && s.EndLocate == AGVStaionEnum.A1.ToString()).CountAsync();
// if (input.Qty > intProduct)
// throw Oops.Bah($"输入数量大于可出数量{intProduct}");
// var listTask = new List();
// var TaskNo = GetTaskCode("WCS");
// for (int i = 0; i < input.Qty; i++)
// {
// listTask.Add(new WcsTask()
// {
// TaskNo = "WCS" + DateTime.Now.ToString("yyyyMMdd") + (TaskNo++).ToString().PadLeft(4, '0'),
// TaskType = TaskTypeEnum.Move,
// Type = PLCTypeEnum.AGV,
// StartLocate = AGVStaionEnum.Z11.ToString(),
// EndLocate = AGVStaionEnum.A1.ToString(),
// PalletNo = "",
// Status = TaskStatusEnum.Wait,
// Levels = 10,
// Origin = "PDA"
// });
// }
// await _db.Insertable(listTask).ExecuteCommandAsync();
//}
///
/// 自动生成任务号
///
///
///
[NonAction]
public static int GetTaskCode(string codeFlag = "WCS")
{
var list = _db.Queryable().Where(m => m.TaskNo.StartsWith("WCS")).ToList();
string maxNo = list.Max(m => m.TaskNo);
if (!string.IsNullOrEmpty(maxNo))
{
maxNo = maxNo.Substring(codeFlag.Length);
}
//获取数据库时间八位
string date = DateTime.Now.ToString("yyyyMMdd").Trim();
int no = 0;
if (string.IsNullOrEmpty(maxNo))
{
no = 1;
}
else
{
if (maxNo.Length == 12 && maxNo.Substring(0, 8) == date)
{
int lastNo = Convert.ToInt32(maxNo.Substring(8, 4)) + 1;
no = lastNo;
}
else
{
no = 1;
}
}
return no;
}
///
/// 完成任务
///
///
///
[HttpPost]
public async Task FinishTask(WcsTask input)
{
if (input.TaskNo.IsNullOrEmpty())
throw Oops.Bah("任务号不能为空");
var modTask = await _db.Queryable().FirstAsync(s => s.TaskNo == input.TaskNo);
if (modTask == null)
throw Oops.Bah("找不到任务");
if (modTask.Status > TaskStatusEnum.Doing)
throw Oops.Bah("任务状态不对");
modTask.FinishDate = DateTime.Now;
modTask.Status = TaskStatusEnum.Complete;
await _db.Updateable(modTask).ExecuteCommandAsync();
var taskMonitor = new WcsTaskMonitor()
{
TaskNo = modTask.TaskNo,
InteractiveMsg = $"WMS调用完成任务"
};
_db.Insertable(taskMonitor).ExecuteCommand();
//下发任务日志
HubUtil.PublicTask(modTask.Adapt());
HubUtil.PublicTaskMonitor(taskMonitor.Adapt());
}
///
/// 查询缓存位状态
///
///
[HttpPost]
public async Task> QueryCacheStorage()
{
string[] listPallet = new[] {
"cache_Z11","cache_Z12","cache_Z13",
"cache_Z21","cache_Z22","cache_Z23",
"cache_Z31","cache_Z32","cache_Z33",
"cache_Z41","cache_Z42","cache_Z43",
"cache_Z51","cache_Z52","cache_Z53",
};
Dictionary dic = new Dictionary();
foreach (var mod in listPallet)
{
dic.Add(mod.Split('_')[1], await _sysConfigService.GetConfigValue(mod));
}
return dic;
}
///
/// 修改缓存位状态
///
///
[HttpPost]
public async Task ChangeCacheStatus(StorageCacheStatus input)
{
Type type = input.GetType();
foreach (var item in type.GetProperties())
{
string value = "";
var result = item.GetValue(input);
if (!result.IsNullOrEmpty())
{
if ((bool)item.GetValue(input))
value = "True";
else
value = "False";
await _sysConfigService.UpdateConfigValue("cache_" + item.Name, value);
}
}
}
///
/// 查询小车正在执行的任务
///
///
[HttpPost]
public async Task AGVTask()
{
return await _db.Queryable().Where(s => s.Type == PLCTypeEnum.AGV && s.Status == TaskStatusEnum.Doing).FirstAsync();
}
///
/// 取消小车正在执行的任务
///
///
[HttpPost]
public async Task CancelTask(WcsTask input)
{
await App.GetService().Finsh(new UpdateWcsTaskInput() { Id = input.Id, Status = TaskStatusEnum.Cancell });
}
}