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; namespace WCS.Application; /// <summary> /// 任务表æœåŠ¡ /// </summary> [ApiDescriptionSettings(ApplicationConst.GroupName, Order = 100)] public class WcsTaskService : IDynamicApiController, ITransient { private static readonly ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId); private readonly SqlSugarRepository<WcsTask> _wcsTaskRep; private readonly IHubContext<TaskLogHub, ITaskLogHub> _taskLogHubContext; private readonly SqlSugarRepository<WcsCheckTask> _wcsCheckTaskRep; private readonly SqlSugarRepository<WcsMateialPzInfo> _wcsMateialPzInfoRep; public WcsTaskService(SqlSugarRepository<WcsTask> wcsTaskRep, IHubContext<TaskLogHub, ITaskLogHub> taskLogHubContext, SqlSugarRepository<WcsCheckTask> wcsCheckTaskRep, SqlSugarRepository<WcsMateialPzInfo> wcsMateialPzInfoRep) { _wcsTaskRep = wcsTaskRep; _taskLogHubContext = taskLogHubContext; _wcsCheckTaskRep = wcsCheckTaskRep; _wcsMateialPzInfoRep = wcsMateialPzInfoRep; } /// <summary> /// 分页查询任务表 /// </summary> /// <param name="input"></param> /// <returns></returns> [HttpPost] [ApiDescriptionSettings(Name = "Page")] [DisplayName("分页查询任务表")] public async Task<SqlSugarPagedList<WcsTaskOutput>> 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<WcsTaskOutput>(); return await query.OrderBy(o=>o.Levels).OrderByDescending(o=>o.CreateTime) .OrderByDescending(m=>m.Status).OrderBy(m=>m.TaskNo) .ToPagedListAsync(input.Page, input.PageSize); } /// <summary> /// å¢žåŠ ä»»åŠ¡è¡¨ /// </summary> /// <param name="input"></param> /// <returns></returns> [HttpPost] [ApiDescriptionSettings(Name = "Add")] [DisplayName("å¢žåŠ ä»»åŠ¡è¡¨")] public async Task<long> 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<WcsTask>(); entity.Origin = "WCS"; if (string.IsNullOrEmpty(entity.TaskNo)) { //生æˆä»»åŠ¡å· entity.TaskNo = GetTaskCode(); if (string.IsNullOrEmpty(entity.TaskNo)) { throw Oops.Bah("任务å·ç”Ÿæˆå¤±è´¥"); } } #region æœºå™¨äººæ‹†åž›åˆ†é…æ‹†åž›å·¥ä½ if (entity.UnstackingMode== UnstackingModeEnum.Machine) { //åˆ†æ‹£ä»»åŠ¡ä¿¡æ¯ List<TaskPortDto> taskPortList = await _wcsCheckTaskRep.Context.Queryable<WcsCheckTask>().Where(w => w.RoboatType == PLCTypeEnum.StackingRobot).Select<TaskPortDto>().ToListAsync(); if (taskPortList.Count <= 0) { throw Oops.Bah("拆垛工ä½å¼‚常"); } var taskList = await _wcsTaskRep.Context.Queryable<WcsTask>().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; } /// <summary> /// åˆ é™¤ä»»åŠ¡è¡¨ /// </summary> /// <param name="input"></param> /// <returns></returns> [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); //çœŸåˆ é™¤ } /// <summary> /// 更新任务表 /// </summary> /// <param name="input"></param> /// <returns></returns> [HttpPost] [ApiDescriptionSettings(Name = "Update")] [DisplayName("更新任务表")] public async Task Update(UpdateWcsTaskInput input) { var entity = input.Adapt<WcsTask>(); await _wcsTaskRep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); } /// <summary> /// 获å–任务表 /// </summary> /// <param name="input"></param> /// <returns></returns> [HttpGet] [ApiDescriptionSettings(Name = "Detail")] [DisplayName("获å–任务表")] public async Task<WcsTask> Detail([FromQuery] QueryByIdWcsTaskInput input) { return await _wcsTaskRep.GetFirstAsync(u => u.Id == input.Id); } /// <summary> /// 获å–任务表列表 /// </summary> /// <param name="input"></param> /// <returns></returns> [HttpGet] [ApiDescriptionSettings(Name = "List")] [DisplayName("获å–任务表列表")] public async Task<List<WcsTaskOutput>> List([FromQuery] PageWcsTaskInput input) { return await _wcsTaskRep.AsQueryable().Select<WcsTaskOutput>().ToListAsync(); } /// <summary> /// 完æˆ/å–æ¶ˆä»»åŠ¡è¡¨ /// </summary> /// <param name="input"></param> /// <returns></returns> [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.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(); //await _taskLogHubContext.Clients.All.PublicTask(modTask.Adapt<WcsTaskOutput>()); //await _taskLogHubContext.Clients.All.PublicTaskMonitor(modTaskMonitor.Adapt<WcsTaskMonitorOutput>()); #region //åˆ†æ‹£ä»»åŠ¡ä¿¡æ¯ var checkTaskList = _wcsCheckTaskRep.Context.Queryable<WcsCheckTask>().Where(w => w.TaskNo == modTask.TaskNo && w.Status == "1").ToList(); foreach (var item in checkTaskList) { item.OrderNo = ""; item.TaskNo = ""; item.LotNo = ""; item.SkuNo = ""; item.SkuName = ""; item.BoxType = ""; item.Qty = 0; item.PZNo = ""; item.Status = "0";//未绑定 } //更新分拣任务 await _wcsCheckTaskRep.AsUpdateable(checkTaskList).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); #endregion } else { throw Oops.Oh("任务状æ€å¼‚常"); } } // <summary> /// 手动给WMSä¸Šä¼ ä»»åŠ¡ /// </summary> /// <param name="input"></param> /// <returns></returns> [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任务完æˆ"; } else { Log.Error(string.Format("æ‰‹åŠ¨ä¸Šä¼ WMS任务å馈失败:StatusCode:{0};Msg:{1}", modResponseTask.StatusCode, modResponseTask.Msg)); } // æ’入交互日志 _db.Insertable(modTaskMonitor).ExecuteCommand(); //下å‘任务日志 HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt<WcsTaskMonitorOutput>()); } /// <summary> /// 任务置顶 /// </summary> /// <param name="input"></param> /// <returns></returns> [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<string> _editTaskNoList = new List<string>(); //傍使·±åº¦ 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<WcsTask>().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<WcsTask>().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<WcsTask>().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(); } /// <summary> /// 自动生æˆä»»åŠ¡å· /// </summary> /// <param name="codeFlag"></param> /// <returns></returns> [NonAction] public string GetTaskCode(string codeFlag="WCS") { var list = _db.Queryable<WcsTask>().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; } }