Files
tnb.server/WarehouseMgr/Tnb.WarehouseMgr/DeviceProviderService.cs

371 lines
17 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 JNPF;
using JNPF.Common.Core.Manager;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Manager;
using JNPF.Common.Net;
using JNPF.Common.Security;
using JNPF.EventBus;
using JNPF.EventHandler;
using JNPF.Logging;
using JNPF.Systems.Entitys.System;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using SqlSugar;
using Tnb.Common.Extension;
using Tnb.EquipMgr.Entities;
using Tnb.WarehouseMgr.Entities;
using Tnb.WarehouseMgr.Entities.Configs;
using Tnb.WarehouseMgr.Entities.Consts;
using Tnb.WarehouseMgr.Entities.Dto;
using Tnb.WarehouseMgr.Entities.Dto.Inputs;
using Tnb.WarehouseMgr.Entities.Dto.Outputs;
using Tnb.WarehouseMgr.Entities.Entity;
using Tnb.WarehouseMgr.Entities.Enums;
using Tnb.WarehouseMgr.Interfaces;
namespace Tnb.WarehouseMgr
{
/// <summary>
/// Wms设备接口提供程序服务类
/// </summary>
public class DeviceProviderService : BaseWareHouseService<DeviceProviderService>
{
private readonly ISqlSugarClient _db;
private readonly IWareHouseService _wareHouseService;
private readonly ICacheManager _cacheManager;
private readonly IEventPublisher _eventPublisher;
private readonly IUserManager _userManager;
private readonly IElevatorControlService _elevatorControlService;
private readonly ElevatorControlConfiguration _eleCtlCfg = App.Configuration.Build<ElevatorControlConfiguration>();
private readonly ILoggerFactory _loggerFactory;
public DeviceProviderService(ISqlSugarRepository<WmsInstockH> repository, IWareHouseService wareHouseService,
ICacheManager cacheManager,
IEventPublisher eventPublisher,
IUserManager userManger,
IElevatorControlService elevatorControlService
) //: base(repository.AsSugarClient())
{
_db = repository.AsSugarClient();
_wareHouseService = wareHouseService;
_cacheManager = cacheManager;
_eventPublisher = eventPublisher;
_userManager = userManger;
_elevatorControlService = elevatorControlService;
_ = InitializationTask;
}
/// <summary>
/// 创建任务链
/// </summary>
/// <returns></returns>
[HttpPost, NonUnify]
public async Task<Result> CreateTaskChain()
{
Logger.LogInformation("fasdfadsfadsfasdfasdfadsfasdfadsfadsfasdfasdfasdfasdfas");
return await Task.FromResult<Result>(null);
}
/// <summary>
/// 取货确认/申请取货
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost, NonUnify, AllowAnonymous]
public async Task<Result> LoadConfirm(ConfirmInput input)
{
Log.Information("取货确认..................");
WmsElevatorH elevator = await _db.Queryable<WmsElevatorH>().LeftJoin<WmsElevatorD>((a, b) => a.id == b.bill_id)
.LeftJoin<WmsDistaskH>((a, b, c) => b.location_id == c.startlocation_id)
.LeftJoin<WmsPointH>((a, b, c, d) => c.startlocation_id == d.location_id)
.Where((a, b, c, d) => d.point_code == input.sourceName && input.taskCode.Contains(c.bill_code))
.Select((a, b, c, d) => new WmsElevatorH
{
distask_id = c.id,
device_id = c.device_id,
}, true)
.FirstAsync();
if (elevator.IsNull())
{
Logger.Error("未找到匹配的电梯任务", new Exception($"根据参数,sourceName:{input.sourceName},taskCode:{input.taskCode},未找到匹配的电梯任务"));
return await ToApiResult(HttpStatusCode.InternalServerError, $"根据参数,sourceName:{input.sourceName},taskCode:{input.taskCode},未找到匹配的电梯任务");
}
try
{
Logger.Information($"当前任务Id:{elevator.distask_id}");
if (s_elevatorMap.TryGetValue(elevator.device_id, out object? elevatorCode))
{
string devName = elevatorCode?.ToString() ?? _eleCtlCfg.DevName;
(int sysStatus, int runStatus, int floorNo, int doorStatus, int agvStatus) = await _elevatorControlService.GetElevatorStatus(devName, CancellationToken.None);
Logger.Information($"电梯当前状态->系统状态:{sysStatus.ToEnum<EnumSysStatus>()},运行状态:{runStatus.ToEnum<EnumRunStatus>()},Agv状态:{agvStatus.ToEnum<EnumAgvStatus>()},当前楼层:{floorNo}");
{
if (doorStatus.ToEnum<EnumDoorStatus>() != EnumDoorStatus.)
{
_ = await _elevatorControlService.SendOpenCloseCmd(devName, 3); //发送电梯前门开门指令
}
if (sysStatus.ToEnum<EnumSysStatus>() == EnumSysStatus. && runStatus.ToEnum<EnumRunStatus>() == EnumRunStatus.)
{
//elevator.current_floor = floor;
//await _db.Updateable(elevator).UpdateColumns(it => it.current_floor).ExecuteCommandAsync();
return await ToApiResult(HttpStatusCode.OK, "成功");
}
return await ToApiResult(HttpStatusCode.InternalServerError, "电梯还未开门,请重试!");
}
}
}
catch (Exception)
{
return await ToApiResult(HttpStatusCode.InternalServerError, "请重试!");
throw;
}
return await ToApiResult(HttpStatusCode.OK, "未启用");
}
/// <summary>
/// 放货确认/申请放货
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost, NonUnify, AllowAnonymous]
public async Task<Result> UnloadConfirm(ConfirmInput input)//
{
Logger.Information("放货确认..................");
try
{
//根据Agv传递的参数获取对应的电梯
WmsElevatorH elevator = await _db.Queryable<WmsElevatorH>().LeftJoin<WmsElevatorD>((a, b) => a.id == b.bill_id)
.LeftJoin<WmsDistaskH>((a, b, c) => b.location_id == c.endlocation_id)
.LeftJoin<WmsPointH>((a, b, c, d) => c.endlocation_id == d.location_id)
.Where((a, b, c, d) => d.point_code == input.targetName && c.bill_code == input.taskCode)
.Select((a, b, c, d) => new WmsElevatorH
{
end_floor = SqlFunc.ToInt32(c.end_floor),
distask_id = c.id,
}, true)
.FirstAsync();
if (elevator.IsNull())
{
throw new Exception($"根据参数,sourceName:{input.sourceName},taskCode:{input.taskCode},未找到匹配的电梯任务");
}
if (s_elevatorMap.TryGetValue(elevator.elevator_id, out object? elevatorCode))
{
string devName = elevatorCode?.ToString() ?? _eleCtlCfg.DevName;
(int sysStatus, int runStatus, int floorNo, int doorStatus, int agvStatus) = await _elevatorControlService.GetElevatorStatus(devName, CancellationToken.None);//elevator.elevator_code
Logger.Information($"电梯当前状态->系统状态:{sysStatus.ToEnum<EnumSysStatus>()},运行状态:{runStatus},门状态:{doorStatus},Agv状态:{agvStatus},当前楼层:{floorNo}");
//判断Agv电梯是否进入状态
if (agvStatus != (int)EnumAgvStatus.AGV运行状态)
{
await _elevatorControlService.WriteTagAsync(devName, ElevatorConsts.AGVControl, 1);
}
Logger.Information("目前正常");
//电梯到达目标楼层后,判断当前电梯门状态是否为开门到位保持状态
if (doorStatus != (int)EnumDoorStatus.)
{
_ = await _elevatorControlService.SendOpenCloseCmd(devName, 3); //发送电梯前门开门指令
}
if (sysStatus == (int)EnumSysStatus. && runStatus == (int)EnumRunStatus.
&& doorStatus == (int)EnumDoorStatus.)
{
Log.Information("进入开门状态,马上要成功了");
try
{
/* elevator.current_floor = elevator.end_floor;
await _db.Updateable(elevator).UpdateColumns(it => it.current_floor).ExecuteCommandAsync();*/
}
catch (Exception ex)
{
Logger.LogError("更新延迟队列异常", ex);
throw;
}
return await ToApiResult(HttpStatusCode.OK, "成功");
}
}
return await ToApiResult(HttpStatusCode.InternalServerError, "电梯还未开门,请重试!");
}
catch (Exception ex)
{
Logger.Error("放货确认失败", ex);
return await ToApiResult(HttpStatusCode.InternalServerError, "电梯还未开门,请重试!");
throw;
}
}
/// <summary>
/// 任务链状态上报
/// </summary>
/// <returns></returns>
[HttpPost, NonUnify, AllowAnonymous]
public async Task<Result> TaskChainCallBack(TaskChainCallBackInput input)
{
try
{
Logger.Information($"任务链编号:{input.taskChainCode},状态:{input.status},设备ID{input.deviceID}");
/*switch (input.status)
{
case "CREATED": break;
case "ALLOCATED": break;
case "PROCESSING":
//if (await _cacheManager.GetAsync($"{input.taskChainCode}") == "任务链状态上报,上报状态PROCESSING") break;
if (input.taskChainCode.Trim().IsNullOrEmpty())
{
break;
}
List<WmsDistaskH> disTasks = await _db.Queryable<WmsDistaskH>().Where(it => it.bill_code.Contains(input.taskChainCode)).ToListAsync();
List<EqpEquipment> eps = await _db.Queryable<EqpEquipment>().Where(it => it.code.Contains(input.deviceID)).ToListAsync();
TaskExecuteUpInput taskExecuteUpInput = new()
{
disTaskIds = disTasks.Select(x => x.id).ToList(),
EqpIds = eps.Select(x => x.id).ToList(),
};
await _wareHouseService.TaskExecute(taskExecuteUpInput); break;
case "CANCELLED": break;
case "SUCCEED": break;
case "FAILURE": break;
case "FINISHED": break;
default: break;
}*/
if (input.taskChainCode.Trim().IsNullOrEmpty())
{
return await ToApiResult(HttpStatusCode.InternalServerError, "请重试!");
}
List<WmsDistaskH> disTasks = await _db.Queryable<WmsDistaskH>().Where(it => it.bill_code.Contains(input.taskChainCode)).ToListAsync();
List<EqpEquipment> eps = await _db.Queryable<EqpEquipment>().Where(it => it.code.Contains(input.deviceID)).ToListAsync();
TaskExecuteUpInput taskExecuteUpInput = new()
{
disTaskIds = disTasks.Select(x => x.id).ToList(),
EqpIds = eps.Select(x => x.id).ToList(),
};
await _wareHouseService.TaskExecute(taskExecuteUpInput);
ConnectionConfigOptions opts = App.GetOptions<ConnectionConfigOptions>();
UserAgent userAgent = new(App.HttpContext);
//写系统日志
await _eventPublisher.PublishAsync(new LogEventSource("Log:CreateOpLog", opts, new SysLogEntity
{
Id = SnowflakeIdHelper.NextId(),
Category = 4,
UserId = _userManager.UserId,
UserName = _userManager.User.RealName,
IPAddress = NetHelper.Ip,
RequestURL = App.HttpContext.Request.Path,
RequestMethod = App.HttpContext.Request.Method,
Json = $"任务链状态上报,任务链编号:{input.taskChainCode},上报状态:{input.status},设备编号:{input.deviceID}",
PlatForm = string.Format("{0}-{1}", userAgent.OS.ToString(), userAgent.RawValue),
CreatorTime = DateTime.Now
}));
}
catch (Exception ex)
{
Logger.Error("任务链状态上报", ex);
return await ToApiResult(HttpStatusCode.InternalServerError, "请重试!");
throw;
}
return await ToApiResult(HttpStatusCode.OK, "成功");
}
/// <summary>
/// 任务状态上报
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost, NonUnify, AllowAnonymous]
public async Task<Result> TaskCallback(TaskCallBackInput input)
{
Log.Information($"接收参数:{JsonConvert.SerializeObject(input)}");
try
{
List<WmsDistaskH> disTasks = await _db.Queryable<WmsDistaskH>().Where(it => it.bill_code.Contains(input.taskCode)).ToListAsync();
if (input.action == "LOAD")
{
TaskExecuteAfterUpInput taskExecuteAfterUpInput = new()
{
disTaskIds = disTasks.Select(x => x.id).ToList()
};
await _wareHouseService.TaskExecuteAfter(taskExecuteAfterUpInput);
Logger.Information($"Agv取货完成,任务Id:{string.Join(",", disTasks.Select(x => x.id))}");
WmsElevatorUnexecute elevatorQueueItem = await _db.Queryable<WmsElevatorUnexecute>().FirstAsync(it => disTasks.Select(x => x.id).Contains(it.distask_id) && it.task_status == "执行中");
if (elevatorQueueItem != null)
{
Logger.Information("开始进入关门流程");
int doorStatus = await _elevatorControlService.GetTagAsync(elevatorQueueItem.elevator_code, ElevatorConsts.DoorStatus);
if (doorStatus.ToEnum<EnumDoorStatus>() != EnumDoorStatus.)
{
_ = await _elevatorControlService.SendOpenCloseCmd(elevatorQueueItem.elevator_code, 4); //向电梯发送前门关门指令
_ = await _db.Deleteable(elevatorQueueItem).ExecuteCommandAsync();
}
}
}
else if (input.action == "UNLOAD")
{
TaskCompleUpInput taskCompleUpInput = new()
{
disTaskIds = disTasks.Select(x => x.id).ToList()
};
await _wareHouseService.TaskComplate(taskCompleUpInput);
}
}
catch (Exception ex)
{
Logger.Error("任务状态上报出现错误", ex);
return await ToApiResult(HttpStatusCode.InternalServerError, "请重试!");
throw;
}
finally
{
_ = InvokeGenPretaskExcute();
}
return await ToApiResult(HttpStatusCode.OK, "成功");
}
/// <summary>
/// 申请进出电梯
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost, NonUnify, AllowAnonymous]
public async Task<Result> ElevatorConfirm(ConfirmInput input)
{
try
{
List<WmsElevatorH> eles = await _db.Queryable<WmsElevatorH>().LeftJoin<WmsElevatorD>((a, b) => a.id == b.bill_id)
.LeftJoin<WmsDistaskH>((a, b, c) => b.location_id == c.startlocation_id)
.Where((a, b, c) => c.startlocation_code == input.sourceName && c.bill_code == input.taskCode)
.ToListAsync();
}
catch (Exception)
{
return await ToApiResult(HttpStatusCode.InternalServerError, "请重试!");
throw;
}
return await ToApiResult(HttpStatusCode.OK, "未启用");
}
}
}