using AngleSharp.Dom;
using COSXML.Network;
using DocumentFormat.OpenXml.Drawing.Charts;
using DocumentFormat.OpenXml.Math;
using Elastic.Clients.Elasticsearch.Tasks;
using Furion.DatabaseAccessor;
using Furion.Logging;
using Microsoft.AspNetCore.SignalR;
using NewLife;
using WCS.Application.Entity;
using WCS.Application.Service.WcsTask.Dto;
using WCS.Application.Util;
namespace WCS.Application;
///
/// 任务表服务
///
[ApiDescriptionSettings(ApplicationConst.GroupName, Order = 100)]
public class WcsTaskService : IDynamicApiController, ITransient
{
private static readonly ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId);
private readonly SqlSugarRepository _wcsTaskRep;
private readonly IHubContext _taskLogHubContext;
private readonly SqlSugarRepository _wcsCheckTaskRep;
private readonly SqlSugarRepository _wcsMateialPzInfoRep;
public WcsTaskService(SqlSugarRepository wcsTaskRep, IHubContext taskLogHubContext, SqlSugarRepository wcsCheckTaskRep, SqlSugarRepository wcsMateialPzInfoRep)
{
_wcsTaskRep = wcsTaskRep;
_taskLogHubContext = taskLogHubContext;
_wcsCheckTaskRep = wcsCheckTaskRep;
_wcsMateialPzInfoRep = wcsMateialPzInfoRep;
}
///
/// 分页查询任务表
///
///
///
[HttpPost]
[ApiDescriptionSettings(Name = "Page")]
[DisplayName("分页查询任务表")]
public async Task> Page(PageWcsTaskInput input)
{
input.SearchKey = input.SearchKey?.Trim();
var query = _wcsTaskRep.AsQueryable()
.WhereIF(!string.IsNullOrEmpty(input.SearchKey), u =>
u.TaskNo.Contains(input.SearchKey)
)
.WhereIF(!string.IsNullOrWhiteSpace(input.TaskNo), u => u.TaskNo.Contains(input.TaskNo.Trim()))
.WhereIF(input.TaskType.HasValue, u => u.TaskType == input.TaskType)
.WhereIF(input.Status.HasValue, u => u.Status == input.Status)
.WhereIF(!string.IsNullOrWhiteSpace(input.PalletNo), u => u.PalletNo.Contains(input.PalletNo.Trim()))
.WhereIF(!string.IsNullOrWhiteSpace(input.Origin), u => u.Origin.Contains(input.Origin.Trim()))
.Select();
return await query.OrderByDescending(o => o.Id)
.ToPagedListAsync(input.Page, input.PageSize);
}
///
/// 增加任务表
///
///
///
[HttpPost]
[ApiDescriptionSettings(Name = "Add")]
[DisplayName("增加任务表")]
public async Task Add(AddWcsTaskInput input)
{
if (await _wcsTaskRep.AsQueryable().AnyAsync(s => s.TaskNo == input.TaskNo))
{
throw Oops.Bah("任务号重复");
}
if (input.UnstackingMode == UnstackingModeEnum.Machine)
{
if (string.IsNullOrEmpty(input.SkuNo) || string.IsNullOrEmpty(input.SkuName))
{
throw Oops.Bah("机器人拣货,物料和批次信息不能为空");
}
}
var entity = input.Adapt();
entity.Origin = "WCS";
if (string.IsNullOrEmpty(entity.TaskNo))
{
//生成任务号
entity.TaskNo = GetTaskCode();
// 判断是否穿梭车任务
if (entity.Type != PLCTypeEnum.AGV)
{
entity.TaskId = FourWayCarUtil.GetTaskId();
}
if (string.IsNullOrEmpty(entity.TaskNo))
{
throw Oops.Bah("任务号生成失败");
}
}
#region 机器人拆垛分配拆垛工位
if (entity.UnstackingMode == UnstackingModeEnum.Machine)
{
//分拣任务信息
List taskPortList = await _wcsCheckTaskRep.Context.Queryable().Where(w => w.RoboatType == PLCTypeEnum.StackingRobot).Select().ToListAsync();
if (taskPortList.Count <= 0)
{
throw Oops.Bah("拆垛工位异常");
}
var taskList = await _wcsTaskRep.Context.Queryable().Where(w => w.Status == 0 && w.IsBind == 0 && w.TaskType == TaskTypeEnum.Out).ToListAsync();
foreach (var item in taskPortList)
{
item.PortCount = taskList.Where(w => w.StationNum == item.Port).Count();
}
var portInfo = taskPortList.OrderBy(o => o.PortCount).ThenBy(o => o.LineNO).First();
//拆垛工位号
entity.StationNum = portInfo.Port;
}
#endregion
await _wcsTaskRep.InsertAsync(entity);
return entity.Id;
}
///
/// 删除任务表
///
///
///
[HttpPost]
[ApiDescriptionSettings(Name = "Delete")]
[DisplayName("删除任务表")]
public async Task Delete(DeleteWcsTaskInput input)
{
var entity = await _wcsTaskRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
await _wcsTaskRep.FakeDeleteAsync(entity); //假删除
//await _wcsTaskRep.DeleteAsync(entity); //真删除
}
///
/// 更新任务表
///
///
///
[HttpPost]
[ApiDescriptionSettings(Name = "Update")]
[DisplayName("更新任务表")]
public async Task Update(UpdateWcsTaskInput input)
{
var entity = input.Adapt();
await _wcsTaskRep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
}
///
/// 获取任务表
///
///
///
[HttpGet]
[ApiDescriptionSettings(Name = "Detail")]
[DisplayName("获取任务表")]
public async Task Detail([FromQuery] QueryByIdWcsTaskInput input)
{
return await _wcsTaskRep.GetFirstAsync(u => u.Id == input.Id);
}
///
/// 获取任务表列表
///
///
///
[HttpGet]
[ApiDescriptionSettings(Name = "List")]
[DisplayName("获取任务表列表")]
public async Task> List([FromQuery] PageWcsTaskInput input)
{
return await _wcsTaskRep.AsQueryable().Select().ToListAsync();
}
///
/// 完成/取消任务表
///
///
///
[HttpPost]
[ApiDescriptionSettings(Name = "Finsh")]
[DisplayName("完成/取消任务表")]
[UnitOfWork]
public async Task Finsh(UpdateWcsTaskInput input)
{
if (input.Status == TaskStatusEnum.Complete || input.Status == TaskStatusEnum.Cancell)
{
var modTask = await _wcsTaskRep.GetByIdAsync(input.Id);
if (modTask.Status > TaskStatusEnum.Doing)
throw Oops.Oh("任务状态异常");
if (input.Type == PLCTypeEnum.AGV)
PLCService.AGVStatus = false;
if (input.Status == TaskStatusEnum.Cancell && input.Type == PLCTypeEnum.AGV && modTask.Status == TaskStatusEnum.Doing)
{
CancelTaskModel model = new CancelTaskModel()
{
ReqCode = Guid.NewGuid().ToString("N"),
TaskCode = modTask.TaskNo,
ReqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
ForceCancel = "0"
};
var response = new HttpService().CancelTask(model).Result;
if (response.code == "0")
{
WcsTaskMonitor modTaskMonitor = new WcsTaskMonitor()
{
TaskNo = modTask.TaskNo,
PlcId = 0,
PlcName = "",
Status = TaskStatusEnum.Complete,
StartLocat = modTask.StartLocate,
EndLocat = modTask.EndLocate,
InteractiveMsg = "任务已手动取消",
PalletNo = modTask.PalletNo
};
await _wcsTaskRep.Context.Insertable(modTaskMonitor).ExecuteCommandAsync();
HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt());
}
return;
}
else
{
if (input.Status == TaskStatusEnum.Complete)
{
modTask.IsSuccess = TaskSuccessEnum.Success;
modTask.FinishDate = DateTime.Now;//完成时间
}
else
{
modTask.IsSuccess = TaskSuccessEnum.Fail;
modTask.CancelDate = DateTime.Now;//取消时间
}
modTask.Status = input.Status;
modTask.Levels = 999;
await _wcsTaskRep.Context.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 = input.Status == TaskStatusEnum.Complete ? "任务已手动完成" : "任务已手动取消",
PalletNo = modTask.PalletNo
};
await _wcsTaskRep.Context.Insertable(modTaskMonitor).ExecuteCommandAsync();
HubUtil.PublicTask(modTask.Adapt());
HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt());
}
}
else
{
throw Oops.Oh("任务状态异常");
}
}
//
/// 手动给WMS上传任务
///
///
///
[HttpPost]
[ApiDescriptionSettings(Name = "UploadTask")]
[DisplayName("手动给WMS上传任务")]
public async Task UploadTask(UpdateWcsTaskInput input)
{
var modTask = await _wcsTaskRep.GetByIdAsync(input.Id);
if (modTask.Status != TaskStatusEnum.Complete)
{
throw Oops.Oh("任务状态异常");
}
if (modTask.Origin != "WMS")
{
throw Oops.Oh("该任务来源不是WMS");
}
// 反馈WMS
var requestMode = new TaskRequestWMS()
{
TaskNo = modTask.TaskNo,
PalletNo = modTask.PalletNo,
TaskType = ((int)modTask.TaskType).ToString(),
TaskStatus = ((int)TaskStatusEnum.Complete).ToString()
};
//任务详情
var modTaskMonitor = new WcsTaskMonitor()
{
TaskNo = modTask.TaskNo,
PlcId = 0,
PlcName = "",
PalletNo = modTask.PalletNo,
Status = TaskStatusEnum.Complete,
StartLocat = modTask.StartLocate,
EndLocat = modTask.EndLocate,
InteractiveMsg = $"手动上传给WMS任务完成"
};
//调用WMS上传任务接口
HttpService httpService = new HttpService();
var modResponseTask = httpService.RequestTask(requestMode).Result;
if (modResponseTask.StatusCode == 0)
{
modTaskMonitor.InteractiveMsg = "手动上传给WMS任务完成";
modTask.IsSuccess = TaskSuccessEnum.Success;
await _db.Updateable(modTask).ExecuteCommandAsync();
}
else
{
Log.Error(string.Format("手动上传WMS任务反馈失败:StatusCode:{0};Msg:{1}", modResponseTask.StatusCode, modResponseTask.Msg));
}
// 插入交互日志
await _db.Insertable(modTaskMonitor).ExecuteCommandAsync();
//下发任务日志
HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt());
}
///
/// 任务置顶
///
///
///
[HttpPost]
[ApiDescriptionSettings(Name = "TopUpTask")]
[DisplayName("任务置顶")]
public async Task TopUpTask(UpdateWcsTaskInput input)
{
var modTask = await _wcsTaskRep.GetByIdAsync(input.Id);
if (modTask.Status != TaskStatusEnum.Wait)
{
throw Oops.Oh("只有等待执行的任务才能置顶!");
}
int editNum = 1;
List _editTaskNoList = new List();
//储位深度
string locatDepth = "";
if (modTask.TaskType == TaskTypeEnum.Out || modTask.TaskType == TaskTypeEnum.Move)//出库任务或入库任务
{
locatDepth = modTask.StartLocate.Substring(modTask.StartLocate.Length - 1, 1);//起始储位深度
if (locatDepth == "2")//判断当前储位是否深度为2,内侧储位
{
string locatString = modTask.StartLocate.Substring(0, modTask.StartLocate.Length - 1) + "1";//获取外侧储位地址
//判断外侧储位是否有等待执行的任务,有就优先执行
var modTask2 = _db.Queryable().First(w => w.IsDelete == false && w.Status == TaskStatusEnum.Wait && w.StartLocate == locatString);
if (modTask2 != null)
{
modTask2.Levels = 1;
await _wcsTaskRep.Context.Updateable(modTask2).UpdateColumns(s => new { s.Levels }).ExecuteCommandAsync();
_editTaskNoList.Add(modTask2.TaskNo);
modTask.Levels = 2;
await _wcsTaskRep.Context.Updateable(modTask).UpdateColumns(s => new { s.Levels }).ExecuteCommandAsync();
_editTaskNoList.Add(modTask.TaskNo);
editNum = 2;
}
else
{
modTask.Levels = 1;
await _wcsTaskRep.Context.Updateable(modTask).UpdateColumns(s => new { s.Levels }).ExecuteCommandAsync();
_editTaskNoList.Add(modTask.TaskNo);
}
}
else
{
modTask.Levels = 1;
await _wcsTaskRep.Context.Updateable(modTask).UpdateColumns(s => new { s.Levels }).ExecuteCommandAsync();
_editTaskNoList.Add(modTask.TaskNo);
}
}
if (modTask.TaskType == TaskTypeEnum.In)//入库任务
{
if (string.IsNullOrEmpty(modTask.EndLocate))
{
throw Oops.Oh("该入库任务还未分配储位,置顶失败!");
}
locatDepth = modTask.EndLocate.Substring(modTask.EndLocate.Length - 1, 1);//目标储位深度
if (locatDepth == "1")//判断当前储位是否深度为1,外侧储位
{
string locatString = modTask.EndLocate.Substring(0, modTask.EndLocate.Length - 1) + "2";//获取内侧储位地址
//判断内侧储位是否有等待执行的任务,有就优先执行
var modTask2 = _db.Queryable().First(w => w.IsDelete == false && w.Status == TaskStatusEnum.Wait && (w.StartLocate == locatString || w.EndLocate == locatString));
if (modTask2 != null)
{
modTask2.Levels = 1;
await _wcsTaskRep.Context.Updateable(modTask2).UpdateColumns(s => new { s.Levels }).ExecuteCommandAsync();
_editTaskNoList.Add(modTask2.TaskNo);
modTask.Levels = 2;
await _wcsTaskRep.Context.Updateable(modTask).UpdateColumns(s => new { s.Levels }).ExecuteCommandAsync();
_editTaskNoList.Add(modTask.TaskNo);
editNum = 2;
}
else
{
modTask.Levels = 1;
await _wcsTaskRep.Context.Updateable(modTask).UpdateColumns(s => new { s.Levels }).ExecuteCommandAsync();
_editTaskNoList.Add(modTask.TaskNo);
}
}
else
{
modTask.Levels = 1;
await _wcsTaskRep.Context.Updateable(modTask).UpdateColumns(s => new { s.Levels }).ExecuteCommandAsync();
_editTaskNoList.Add(modTask.TaskNo);
}
}
//顺延其他置顶任务
var modTaskList = _db.Queryable().Where(w => w.IsDelete == false && w.Status == TaskStatusEnum.Wait && w.Levels != 999 && !_editTaskNoList.Contains(w.TaskNo)).ToList();
foreach (var item in modTaskList)
{
item.Levels += editNum;
}
await _wcsTaskRep.Context.Updateable(modTaskList).UpdateColumns(s => new { s.Levels }).ExecuteCommandAsync();
}
///
/// 自动生成任务号
///
///
///
[NonAction]
public string 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();
string no = "";
if (string.IsNullOrEmpty(maxNo))
{
no = codeFlag + date + "0001";
}
else
{
if (maxNo.Length == 12 && maxNo.Substring(0, 8) == date)
{
int lastNo = Convert.ToInt32(maxNo.Substring(8, 4)) + 1;
no = codeFlag + date + (lastNo.ToString().PadLeft(4, '0'));
}
else
{
no = codeFlag + date + "0001";
}
}
return no;
}
}