diff --git a/backend/BPA.MES.Base.Application/BPA.MES.Base.Application.xml b/backend/BPA.MES.Base.Application/BPA.MES.Base.Application.xml
index f70912c..469fbf0 100644
--- a/backend/BPA.MES.Base.Application/BPA.MES.Base.Application.xml
+++ b/backend/BPA.MES.Base.Application/BPA.MES.Base.Application.xml
@@ -1431,6 +1431,16 @@
工单状态(信息系统 --> 中控系统)
+
+
+ 任务下发成功 回调
+
+
+
+
+ 上下料回调
+
+
名 称 :
@@ -1602,6 +1612,196 @@
主键
+
+
+ 任务完成回报Dto
+
+
+
+
+ 上游系统任务号,全局唯一
+
+
+
+
+ 仓库编号
+
+
+
+
+ 任务快仓系统编号
+
+
+
+
+
+
+
+
+
+ 内部任务类型
+
+
+
+
+ 数据字段
+
+
+
+
+ 上下料交互请求DTO
+
+
+
+
+ AGV编号
+
+
+
+
+ 容器编号,如果一次上/下多个容器,则多个容器用英文逗号分隔
+
+
+
+
+ 上游设备ID
+
+
+
+
+ 上游设备ID,多个用英文逗号分隔
+
+
+
+
+ 快仓任务编号
+
+
+
+
+ 消息ID
+
+
+
+
+ 交互阶段LOAD:上料阶段 UNLOAD:下料阶段
+
+
+
+
+ 上游任务号
+
+
+
+
+ 货到货
+
+
+
+
+ AGV编号
+
+
+
+
+ 容器编号
+
+
+
+
+ 上料点位
+
+
+
+
+ 上料货位编号
+
+
+
+
+ 下料点位
+
+
+
+
+ 下料货位编号
+
+
+
+
+ 是否需要上料交互
+
+
+
+
+ 点到点
+
+
+
+
+ AGV编号
+
+
+
+
+ 容器编号
+
+
+
+
+ 上料点位
+
+
+
+
+ 下料点位
+
+
+
+
+ 是否需要上料交互
+
+
+
+
+ 顶升完成
+
+
+
+
+ 开始移动
+
+
+
+
+ 放下完成
+
+
+
+
+ 任务完成
+
+
+
+
+ 任务取消
+
+
+
+
+ 任务异常取消
+
+
+
+
+ 任务异常完成
+
+
+
+
+ 1) 辊筒货位到货位搬运
+
+
名 称 :AGV线路管理
@@ -1662,6 +1862,69 @@
+
+
+ 下发任务
+
+
+
+
+
+
+ 取消任务
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 任务回调
+
+
+
+
+
+
+ AGV上下料交互请求
+
+
+
+
+
+
+ 下发任务
+
+
+
+
+
+
+ 取消任务
+
+
+
+
+
+
+ 任务回调
+
+
+
+
+
+
+ AGV上下料交互请求
+
+
+
+
名 称 :AGV点位管理
@@ -4496,6 +4759,16 @@
数量
+
+
+ 成品数量限制
+
+
+
+
+ 成品
+
+
分页列表
@@ -4530,6 +4803,13 @@
+
+
+ 获取成品剩余制作数量
+
+
+
+
分页列表
@@ -4571,6 +4851,19 @@
+
+
+ 生成工单时验证成品数量
+
+
+
+
+
+ 获取成品剩余制作数量
+
+
+
+
名 称 :产品分组
@@ -5574,9 +5867,23 @@
+
+
+ 获取物料统计
+
+
+
+
- 获取产品生产统计
+ 获取成品生产统计
+
+
+
+
+
+
+ 获取物料统计
@@ -5828,6 +6135,16 @@
工单工艺步骤Id
+
+
+ 工单Id
+
+
+
+
+ 锅数
+
+
状态
@@ -5931,6 +6248,21 @@
主键
+
+
+ 工单状态
+
+
+
+
+ 起始时间
+
+
+
+
+ 结束时间
+
+
分页
@@ -5946,6 +6278,21 @@
编码
+
+
+ 工单状态
+
+
+
+
+ 起始时间
+
+
+
+
+ 结束时间
+
+
工单下发
diff --git a/backend/BPA.MES.Base.Application/MQTT/MQTTService.cs b/backend/BPA.MES.Base.Application/MQTT/MQTTService.cs
index adfa2c0..cd61c89 100644
--- a/backend/BPA.MES.Base.Application/MQTT/MQTTService.cs
+++ b/backend/BPA.MES.Base.Application/MQTT/MQTTService.cs
@@ -39,7 +39,6 @@ namespace BPA.MES.Base.Application
try
{
payload.MessageId = messageId;
- payload.MessageId = MessageID.WorkOrderIssued;
payload.MsgVersion = new Version(1, 0, 0, 0);
MsgPackage mp = new MsgPackage();
mp.Message = payload;
@@ -68,6 +67,8 @@ namespace BPA.MES.Base.Application
}
return result;
}
+
+
}
public class MqttResult
diff --git a/backend/BPA.MES.Base.Application/MQTT/MessageID.cs b/backend/BPA.MES.Base.Application/MQTT/MessageID.cs
index 9028fcd..e96980f 100644
--- a/backend/BPA.MES.Base.Application/MQTT/MessageID.cs
+++ b/backend/BPA.MES.Base.Application/MQTT/MessageID.cs
@@ -5,7 +5,10 @@
public const int DevcieControl = 1;//设备控制ID
public const int WorkOrderIssued = 2;//工单下发ID
public const int DeviceData = 3;//设备上报数据
+ public const int TaskState = 4;//AGV任务状态上报
+ public const int LoadAndUnload = 8;//AGV上下料上报
public const int PowerId = 12;// 权限验证
public const int StateChange = 13;//状态改变
}
}
+
diff --git a/backend/BPA.MES.Base.Application/MQTT/Topics.cs b/backend/BPA.MES.Base.Application/MQTT/Topics.cs
index 91a9d60..5144bdc 100644
--- a/backend/BPA.MES.Base.Application/MQTT/Topics.cs
+++ b/backend/BPA.MES.Base.Application/MQTT/Topics.cs
@@ -26,6 +26,17 @@
/// 工单状态(信息系统 --> 中控系统)
///
public const string STWorkState = "BPAProline/CentralControl/Proline/WorkState";
-
+
+ ///
+ /// 任务下发成功 回调
+ ///
+ public const string ExecuteReplyTopic = "robotjob.report";
+
+ ///
+ /// 上下料回调
+ ///
+ public const string LoadAndUnloadTopic = "rollerjob.upstreamrequest";
+
+
}
}
diff --git a/backend/BPA.MES.Base.Application/Services/AGVService/Dtos/AGVThirdPartyDto.cs b/backend/BPA.MES.Base.Application/Services/AGVService/Dtos/AGVThirdPartyDto.cs
new file mode 100644
index 0000000..4f6f0ec
--- /dev/null
+++ b/backend/BPA.MES.Base.Application/Services/AGVService/Dtos/AGVThirdPartyDto.cs
@@ -0,0 +1,278 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BPA.MES.Base.Application.Services.AGVService.Dtos
+{
+
+ public class AGVExecuteReplyRequest
+ {
+ public AGVExecuteReplyDto Event { get; set; }
+ }
+ public class AGVExecuteReplyMQTT: IMessage
+ {
+ public AGVExecuteReplyDto Event { get; set; }
+ public int MessageId { get; set; }
+ public Version MsgVersion { get; set; }
+ }
+
+ public class AGVLoadAndUnloadRequest
+ {
+ public AGVLoadAndUnloadDto Event { get; set; }
+ }
+
+ public class AGVLoadAndUnloadMQTT : IMessage
+ {
+ public AGVLoadAndUnloadDto Event { get; set; }
+ public int MessageId { get; set; }
+ public Version MsgVersion { get; set; }
+ }
+
+ ///
+ /// 任务完成回报Dto
+ ///
+ public class AGVExecuteReplyDto
+ {
+ ///
+ /// 上游系统任务号,全局唯一
+ ///
+ public string robotJobId { get; set; }
+
+ ///
+ /// 仓库编号
+ ///
+ public long warehouseId { get; set; }
+
+ ///
+ /// 任务快仓系统编号
+ ///
+ public string jobId { get; set; }
+
+ ///
+ ///
+ ///
+ public string state { get; set; }
+
+ ///
+ /// 内部任务类型
+ ///
+ public string jobType { get; set; }
+
+ ///
+ /// 数据字段
+ ///
+ public PointToPoint jobData { get; set; }
+
+ }
+
+ ///
+ /// 上下料交互请求DTO
+ ///
+ public class AGVLoadAndUnloadDto
+ {
+ ///
+ /// AGV编号
+ ///
+ public string agvCode { get; set; }
+
+ ///
+ /// 容器编号,如果一次上/下多个容器,则多个容器用英文逗号分隔
+ ///
+ public string containerCode { get; set; }
+
+ ///
+ /// 上游设备ID
+ ///
+ public long equipmentId { get; set; }
+
+ ///
+ /// 上游设备ID,多个用英文逗号分隔
+ ///
+ public string equipmentIds { get; set; }
+
+ ///
+ /// 快仓任务编号
+ ///
+ public string jobId { get; set; }
+
+ ///
+ /// 消息ID
+ ///
+ public string msgId { get; set; }
+
+ ///
+ /// 交互阶段LOAD:上料阶段 UNLOAD:下料阶段
+ ///
+ public string command { get; set; }
+
+ ///
+ /// 上游任务号
+ ///
+ public string robotJobId { get; set; }
+
+ }
+
+
+ ///
+ /// 货到货
+ ///
+ public class GoodsToGoods
+ {
+ ///
+ /// AGV编号
+ ///
+ public string agvCode { get; set; }
+
+ ///
+ /// 容器编号
+ ///
+ public string containerCode { get; set; }
+
+ ///
+ /// 上料点位
+ ///
+ public string startPointCode { get; set; }
+
+ ///
+ /// 上料货位编号
+ ///
+ public string startSlotCode { get; set; }
+
+ ///
+ /// 下料点位
+ ///
+ public string targetPointCode { get; set; }
+
+ ///
+ /// 下料货位编号
+ ///
+ public string targetSlotCode { get; set; }
+
+ ///
+ /// 是否需要上料交互
+ ///
+ public bool loadInteractive { get; set; }
+ }
+
+ ///
+ /// 点到点
+ ///
+ public class PointToPoint
+ {
+ ///
+ /// AGV编号
+ ///
+ public string agvCode { get; set; }
+
+ ///
+ /// 容器编号
+ ///
+ public string containerCode { get; set; }
+
+ ///
+ /// 上料点位
+ ///
+ public string startPointCode { get; set; }
+
+ ///
+ /// 下料点位
+ ///
+ public string targetPointCode { get; set; }
+
+ ///
+ /// 是否需要上料交互
+ ///
+ public bool loadInteractive { get; set; }
+ }
+
+ public enum AGVState
+ {
+
+ //任务状态:
+ //1)货架/货位/点到点货架搬运任务枚举:
+ //LIFT_UP_DONE:顶升完成
+ //MOVE_BEGIN:开始移动
+ //PUT_DOWN_DONE:放下完成
+ //DONE:任务完成
+ //CANCEL:任务取消
+ //ABNORMAL_CANCEL:任务异常取消
+ //ABNORMAL_COMPLETED:任务异常完成
+ //2)货位到货位/点到点辊筒料箱搬运任务枚举:
+ //ROLLER_LOAD_DOING:正在上料
+ //ROLLER_LOAD_FINISH:上料完成
+ //ROLLER_UNLOAD_DOING:正在下料
+ //DONE:下料完成
+ //ABNORMAL_CANCEL:任务异常取消
+ //ABNORMAL_COMPLETED:任务异常完成
+ //3)AGV移动任务枚举:
+ //DONE:任务完成
+ //CANCEL:任务取消
+ //ABNORMAL_CANCEL:任务异常取消
+ //ABNORMAL_COMPLETED:任务异常完成
+ //4) 纯料箱任务枚举:
+ //MOVE_BEGIN:开始移动(仅单插臂或单夹报,2.8.1后)
+ //ENTER_STATION:到站
+ //DONE:任务完成
+ //LOAD_COMPLETED:取料完成
+ //UNLOAD_COMPLETED:放料完成
+ //ABNORMAL_CANCEL:任务异常取消ABNORMAL_COMPLETED:任务异常完成
+ //5) 小皮带任务枚举:
+ //DONE:任务完成
+ //6) QuickPick任务枚举:
+ //ENTER_STATION:到站
+ //DONE:任务完成
+ //CANCEL:任务取消
+ //LEAVE_STATION离站
+ //ROLLBACK 回滚(有其他任务,当前任务可不执行)
+
+
+ ///
+ /// 顶升完成
+ ///
+ LIFT_UP_DONE = 1,
+
+ ///
+ /// 开始移动
+ ///
+ MOVE_BEGIN = 2,
+
+ ///
+ /// 放下完成
+ ///
+ PUT_DOWN_DONE = 3,
+
+ ///
+ /// 任务完成
+ ///
+ DONE = 4,
+
+
+ ///
+ /// 任务取消
+ ///
+ CANCEL = 5,
+
+ ///
+ /// 任务异常取消
+ ///
+ ABNORMAL_CANCEL = 6,
+
+ ///
+ /// 任务异常完成
+ ///
+ ABNORMAL_COMPLETED = 7
+
+ }
+
+ public enum jobType
+ {
+ ///
+ /// 1) 辊筒货位到货位搬运
+ ///
+ SLOT_ROLLER_MOVE = 1,
+ POINT_ROLLER_MOVE=2
+ }
+
+}
diff --git a/backend/BPA.MES.Base.Application/Services/AGVService/Services/AGVThirdPartyService.cs b/backend/BPA.MES.Base.Application/Services/AGVService/Services/AGVThirdPartyService.cs
new file mode 100644
index 0000000..6662673
--- /dev/null
+++ b/backend/BPA.MES.Base.Application/Services/AGVService/Services/AGVThirdPartyService.cs
@@ -0,0 +1,124 @@
+using BPA.AGV;
+using BPA.MES.Base.Application.Services.AGVService.Dtos;
+using MQTTnet.Client;
+using MQTTnet.Client.Publishing;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BPA.MES.Base.Application.Services.AGVService.Services
+{
+
+ [AllowAnonymous, NonUnify]
+ [ApiDescriptionSettings("AGV管理", Name = "AgvThirdParty", Tag = "AGV第三方api", KeepName = true, SplitCamelCase = true, KeepVerb = true)]
+ public class AGVThirdPartyService:IAGVThirdPartyService, ITransient, IDynamicApiController
+ {
+ private readonly AGVHandler _aGVHandler;
+ private readonly IMQTTService _MQTTService;
+ public AGVThirdPartyService(AGVHandler aGVHandler, IMQTTService MQTTService)
+ {
+ _aGVHandler = aGVHandler;
+ _MQTTService = MQTTService;
+ }
+
+ ///
+ /// 下发任务
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task ExecuteAsync(KCExecuteRequest cExecuteRequest)
+ {
+
+ if (cExecuteRequest.JobData != null)
+ cExecuteRequest = new KCExecuteRequest
+ {
+ Url = cExecuteRequest.Url,//http://[IP:Port]/api/quicktron/wcs/standardized.robot.job.submit
+ RobotJobId = Guid.NewGuid().ToString(),
+ WarehouseId = cExecuteRequest.WarehouseId,
+ JobPriority = cExecuteRequest.JobPriority,
+ JobPriorityType = cExecuteRequest.JobPriorityType,
+ JobData = new KCJobDataRequest
+ {
+ StartPoint = cExecuteRequest.JobData.StartPoint,
+
+ EndPoint = cExecuteRequest.JobData.EndPoint,
+ }
+ };
+ return await _aGVHandler.ExecuteAsync(cExecuteRequest);
+ }
+
+ ///
+ /// 取消任务
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task CancelAsync(KCCancelRequest kCCancelRequest)
+ {
+ //http://[IP:Port]/api/quicktron/wcs/standardized.robot.job.cancel
+ return await _aGVHandler.CancelAsync(kCCancelRequest);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task RollerJobExecuteAsync(RollerJobRequest rollerJobRequest)
+ {
+ //http://[IP:Port]/api/quicktron/wcs/standardized.roller.job.upstream.response
+ return await _aGVHandler.RollerJobExecuteAsync(rollerJobRequest);
+ }
+
+ ///
+ /// 任务回调
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task ExecuteReplyAsync(AGVExecuteReplyRequest input)
+ {
+ try
+ {
+
+ var data = new AGVExecuteReplyMQTT()
+ {
+ Event = input.Event,
+ };
+ return await _MQTTService.MqttPublish(data, Topics.ExecuteReplyTopic, MessageID.TaskState);
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+ }
+
+
+ ///
+ /// AGV上下料交互请求
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task LoadAndUnloadAsync(AGVLoadAndUnloadRequest input)
+ {
+ try
+ {
+ var data = new AGVLoadAndUnloadMQTT()
+ {
+ Event = input.Event,
+ };
+ return await _MQTTService.MqttPublish(data, Topics.LoadAndUnloadTopic, MessageID.LoadAndUnload);
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+ }
+
+ }
+}
diff --git a/backend/BPA.MES.Base.Application/Services/AGVService/Services/IAGVThirdPartyService.cs b/backend/BPA.MES.Base.Application/Services/AGVService/Services/IAGVThirdPartyService.cs
new file mode 100644
index 0000000..7f07cd8
--- /dev/null
+++ b/backend/BPA.MES.Base.Application/Services/AGVService/Services/IAGVThirdPartyService.cs
@@ -0,0 +1,44 @@
+using BPA.AGV;
+using BPA.MES.Base.Application.Services.AGVService.Dtos;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BPA.MES.Base.Application.Services.AGVService.Services
+{
+ public interface IAGVThirdPartyService
+ {
+
+ ///
+ /// 下发任务
+ ///
+ ///
+ ///
+ Task ExecuteAsync(KCExecuteRequest cExecuteRequest);
+
+ ///
+ /// 取消任务
+ ///
+ ///
+ ///
+ Task CancelAsync(KCCancelRequest kCCancelRequest);
+
+
+ ///
+ /// 任务回调
+ ///
+ ///
+ ///
+ Task ExecuteReplyAsync(AGVExecuteReplyRequest input);
+
+
+ ///
+ /// AGV上下料交互请求
+ ///
+ ///
+ ///
+ Task LoadAndUnloadAsync(AGVLoadAndUnloadRequest input);
+ }
+}
diff --git a/backend/BPA.MES.Base.Application/Services/OrderService/Dtos/OrderBaseDto.cs b/backend/BPA.MES.Base.Application/Services/OrderService/Dtos/OrderBaseDto.cs
index b6ed9bc..6724fbe 100644
--- a/backend/BPA.MES.Base.Application/Services/OrderService/Dtos/OrderBaseDto.cs
+++ b/backend/BPA.MES.Base.Application/Services/OrderService/Dtos/OrderBaseDto.cs
@@ -61,4 +61,18 @@ namespace BPA.MES.Base.Application.Services.OrderService.Dtos
public decimal Number { get; set; }
public WorkOrderStatusEnum? Status { get; set; }
}
+
+ ///
+ /// 成品数量限制
+ ///
+ public class OrderWorkLimit
+ {
+ ///
+ /// 成品
+ ///
+ public string FinalslId { get; set; }
+
+ public decimal Limit { get; set; }
+
+ }
}
diff --git a/backend/BPA.MES.Base.Application/Services/OrderService/Service/IOrderService.cs b/backend/BPA.MES.Base.Application/Services/OrderService/Service/IOrderService.cs
index 527a7e4..c06f8ca 100644
--- a/backend/BPA.MES.Base.Application/Services/OrderService/Service/IOrderService.cs
+++ b/backend/BPA.MES.Base.Application/Services/OrderService/Service/IOrderService.cs
@@ -45,6 +45,13 @@ namespace BPA.MES.Base.Application.Services.OrderService.Service
///
Task OrderAssociationWork(List inputDto);
+ ///
+ /// 获取成品剩余制作数量
+ ///
+ ///
+ ///
+ Task> GetFinalslLImit(string OrderId);
+
Task CodeFirst();
}
}
diff --git a/backend/BPA.MES.Base.Application/Services/OrderService/Service/OrderService.cs b/backend/BPA.MES.Base.Application/Services/OrderService/Service/OrderService.cs
index b854b48..44486a3 100644
--- a/backend/BPA.MES.Base.Application/Services/OrderService/Service/OrderService.cs
+++ b/backend/BPA.MES.Base.Application/Services/OrderService/Service/OrderService.cs
@@ -220,6 +220,8 @@ namespace BPA.MES.Base.Application.Services.OrderService.Service
{
var result = false;
var orderId = inputDto.Select(x => x.OrderId).First();
+ //验证
+ VerifyOrderProduct(inputDto);
_dbContext.Ado.BeginTran();
try
@@ -292,6 +294,72 @@ namespace BPA.MES.Base.Application.Services.OrderService.Service
return true;
}
+ ///
+ /// 生成工单时验证成品数量
+ ///
+ ///
+ private void VerifyOrderProduct(List inputDto)
+ {
+ var orderId = inputDto.Select(x => x.OrderId).First();
+ var data=_dbContext.Queryable((a,b)=>new JoinQueryInfos(
+ JoinType.Left,a.FinalslId==b.Id
+ )).Where((a,b)=>a.OrderId==orderId).
+ Select((a,b)=>new
+ {
+ orderId = a.OrderId,
+ ProductId = a.FinalslId,
+ productName = b.Name,
+ a.Number
+ }).ToList();
+ foreach (var item in data)
+ {
+ var productCount = inputDto.Where(x => x.FinalslId == item.ProductId).Sum(x => x.Number);
+ var count= item.Number - productCount;
+ if (count<0)
+ {
+ throw Oops.Bah($"{item.productName}成品生成工单数量大于订单数量,多【{System.Math.Abs(count)}】");
+ }
+
+ if (count>0)
+ {
+ throw Oops.Bah($"{item.productName}成品生成工单数量小于订单数量,差【{count}】");
+ }
+
+ }
+ }
+
+ ///
+ /// 获取成品剩余制作数量
+ ///
+ ///
+ ///
+ public async Task> GetFinalslLImit(string OrderId)
+ {
+ var result = new List();
+ var orderInfo=_dbContext.Queryable().Where(x=>x.OrderId==OrderId).ToList();
+
+ var list=_dbContext.Queryable((a,b)=>new JoinQueryInfos(
+ JoinType.Left,a.WorkId==b.Id))
+ .Where((a, b) => a.OrderId==OrderId)
+ .Select((a,b)=>new OrderWorkLimit()
+ {
+ FinalslId=b.FinalId,
+ Limit=0
+ }).ToList();
+
+ foreach (var item in orderInfo)
+ {
+ var data=list.Where(x=>x.FinalslId==item.FinalslId).ToList();
+
+ result.Add(new OrderWorkLimit()
+ {
+ FinalslId=item.FinalslId,
+ Limit=item.Number-data.Sum(x=>x.Limit),
+ });
+ }
+ return result;
+
+ }
[HttpGet]
public Task CodeFirst()
diff --git a/backend/BPA.MES.Base.Application/Services/ReportService/Dtos/MaterialsInputDto.cs b/backend/BPA.MES.Base.Application/Services/ReportService/Dtos/MaterialsInputDto.cs
new file mode 100644
index 0000000..d50cac4
--- /dev/null
+++ b/backend/BPA.MES.Base.Application/Services/ReportService/Dtos/MaterialsInputDto.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BPA.MES.Base.Application.Services.ReportService.Dtos
+{
+ public class MaterialsInputDto
+ {
+ public DateTime? StartTime { get; set; }
+ public DateTime? EndTime { get; set; }
+ public string MaterialsName { get; set; }
+ }
+}
diff --git a/backend/BPA.MES.Base.Application/Services/ReportService/Dtos/MaterialsOutDto.cs b/backend/BPA.MES.Base.Application/Services/ReportService/Dtos/MaterialsOutDto.cs
new file mode 100644
index 0000000..bc12347
--- /dev/null
+++ b/backend/BPA.MES.Base.Application/Services/ReportService/Dtos/MaterialsOutDto.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BPA.MES.Base.Application.Services.ReportService.Dtos
+{
+ public class MaterialsOutDto
+ {
+ public string MaterialId { get; set; }
+ public string MaterialName { get; set; }
+ public decimal Count { get; set; }
+ }
+}
diff --git a/backend/BPA.MES.Base.Application/Services/ReportService/IReportService.cs b/backend/BPA.MES.Base.Application/Services/ReportService/IReportService.cs
index 0b4a3fe..b64eedc 100644
--- a/backend/BPA.MES.Base.Application/Services/ReportService/IReportService.cs
+++ b/backend/BPA.MES.Base.Application/Services/ReportService/IReportService.cs
@@ -15,5 +15,12 @@ namespace BPA.MES.Base.Application.Services.ReportService
///
///
Task> GetProductReport(ProductInputDto inputDto);
+
+ ///
+ /// 获取物料统计
+ ///
+ ///
+ ///
+ Task> GetMaterialsReport(MaterialsInputDto inputDto);
}
}
diff --git a/backend/BPA.MES.Base.Application/Services/ReportService/ReportService.cs b/backend/BPA.MES.Base.Application/Services/ReportService/ReportService.cs
index 6f26627..a21d51e 100644
--- a/backend/BPA.MES.Base.Application/Services/ReportService/ReportService.cs
+++ b/backend/BPA.MES.Base.Application/Services/ReportService/ReportService.cs
@@ -18,7 +18,7 @@ namespace BPA.MES.Base.Application.Services.ReportService
}
///
- /// 获取产品生产统计
+ /// 获取成品生产统计
///
///
///
@@ -46,5 +46,70 @@ namespace BPA.MES.Base.Application.Services.ReportService
return res;
}
+
+ ///
+ /// 获取物料统计
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task> GetMaterialsReport(MaterialsInputDto inputDto)
+ {
+ var result = new List();
+ var res = await _dbContext.Queryable
+ ((a, b, c) =>
+ new JoinQueryInfos(
+ JoinType.Left, a.Id == b.WorkId,
+ JoinType.Left, a.FinalId == c.Id)
+ )
+ .Where((a, b, c) => b.Status != WorkOrderStatusEnum.Draft)
+ .WhereIF(inputDto.StartTime.HasVal(), (a, b, c) => b.CreateTime >= inputDto.StartTime.Value)
+ .WhereIF(inputDto.EndTime.HasVal(), (a, b, c) => b.CreateTime >= inputDto.EndTime.Value)
+ .Select((a, b, c) => new
+ {
+ ProductId = a.FinalId,
+ Count = SqlFunc.AggregateSum(Convert.ToInt32(a.Number)),
+ c.RecipeId
+
+ }).ToListAsync();
+ var recipeId = res.Select(x => x.RecipeId).ToList();
+
+ var recipes = await _dbContext.Queryable()
+ .Where(x => recipeId.Contains(x.RecipesId))
+ .Select(x => new
+ {
+ x.MaterialId,
+ x.Weight,
+ x.RecipesId
+ }) .ToListAsync();
+
+ var materialsId= recipes.Select(x => x.MaterialId).ToList();
+
+ var materials = await _dbContext.Queryable()
+ .Where(x=> materialsId.Contains(x.Id))
+ .WhereIF(!string.IsNullOrEmpty(inputDto.MaterialsName),x=>x.Name.Contains(inputDto.MaterialsName))
+ .ToListAsync();
+
+ foreach (var item in materials)
+ {
+ var count = 0;
+ foreach (var item2 in res.GroupBy(x=>x.RecipeId))
+ {
+ var data = recipes.Where(x=>x.RecipesId==item2.Key &&x.MaterialId==item.Id).FirstOrDefault();
+ count=item2.First().Count*Convert.ToInt32(data==null? 0: data.Weight);
+
+ }
+
+ result.Add(new MaterialsOutDto()
+ {
+ MaterialId=item.Id,
+ MaterialName=item.Name,
+ Count= count,
+ });
+ }
+
+ return result;
+ }
+
}
}
diff --git a/backend/BPA.MES.Base.Application/Services/WorkInfoService/Dtos/WorkInfoCraftstepRecordDto.cs b/backend/BPA.MES.Base.Application/Services/WorkInfoService/Dtos/WorkInfoCraftstepRecordDto.cs
index f9fd97a..710c7f1 100644
--- a/backend/BPA.MES.Base.Application/Services/WorkInfoService/Dtos/WorkInfoCraftstepRecordDto.cs
+++ b/backend/BPA.MES.Base.Application/Services/WorkInfoService/Dtos/WorkInfoCraftstepRecordDto.cs
@@ -49,6 +49,14 @@
///
public string WorkCraftstepId { get; set; }
///
+ /// 工单Id
+ ///
+ public string WorkId { get; set; }
+ ///
+ /// 锅数
+ ///
+ public string PotNum { get; set; }
+ ///
/// 状态
///
public RecipeStatus Status { get; set; }
diff --git a/backend/BPA.MES.Base.Application/Services/WorkInfoService/Dtos/WorkInfoDto.cs b/backend/BPA.MES.Base.Application/Services/WorkInfoService/Dtos/WorkInfoDto.cs
index e193795..73947d0 100644
--- a/backend/BPA.MES.Base.Application/Services/WorkInfoService/Dtos/WorkInfoDto.cs
+++ b/backend/BPA.MES.Base.Application/Services/WorkInfoService/Dtos/WorkInfoDto.cs
@@ -73,6 +73,18 @@
/// 主键
///
public string Id { get; set; }
+ ///
+ /// 工单状态
+ ///
+ public WorkOrderStatusEnum?[] Status { get; set; }
+ ///
+ /// 起始时间
+ ///
+ public DateTime? StartTime { get; set; }
+ ///
+ /// 结束时间
+ ///
+ public DateTime? EndTime { get; set; }
}
///
/// 分页
@@ -87,6 +99,18 @@
/// 编码
///
public string Id { get; set; }
+ ///
+ /// 工单状态
+ ///
+ public WorkOrderStatusEnum?[] Status { get; set; }
+ ///
+ /// 起始时间
+ ///
+ public DateTime? StartTime { get; set; }
+ ///
+ /// 结束时间
+ ///
+ public DateTime? EndTime { get; set; }
}
///
/// 工单下发
diff --git a/backend/BPA.MES.Base.Application/Services/WorkInfoService/Services/WorkInfoService.cs b/backend/BPA.MES.Base.Application/Services/WorkInfoService/Services/WorkInfoService.cs
index 36d066c..16ada5e 100644
--- a/backend/BPA.MES.Base.Application/Services/WorkInfoService/Services/WorkInfoService.cs
+++ b/backend/BPA.MES.Base.Application/Services/WorkInfoService/Services/WorkInfoService.cs
@@ -140,6 +140,9 @@ namespace BPA.MES.Base.Application.Services.WorkInfoService.Services
.LeftJoin((a, b, c, d) => d.Id == SqlFunc.Subqueryable().Where(s => s.WorkId == a.Id).OrderByDesc(s => s.CreateTime).Select(s => s.Id))
.WhereIF(!string.IsNullOrEmpty(input.Name), (a, b, c, d) => b.Name.Contains(input.Name))
.WhereIF(!string.IsNullOrEmpty(input.Id), (a, b, c, d) => a.Id.Contains(input.Id))
+ .WhereIF(input.Status != null, (a, b, c, d) => input.Status.Contains(d.Status))
+ .WhereIF(input.StartTime!=null,(a, b, c, d) => input.StartTime<= Convert.ToDateTime(a.CreateTime))
+ .WhereIF(input.EndTime != null, (a, b, c, d) => input.EndTime.Value.AddHours(23).AddMinutes(59).AddSeconds(59) >= Convert.ToDateTime(a.CreateTime))
.Select((a, b, c, d) => new WorkInfoOutput
{
Id = a.Id.SelectAll(),
@@ -163,6 +166,9 @@ namespace BPA.MES.Base.Application.Services.WorkInfoService.Services
.LeftJoin((a, b, c, d) => d.Id == SqlFunc.Subqueryable().Where(s => s.WorkId == a.Id).OrderByDesc(s => s.CreateTime).Select(s => s.Id))
.WhereIF(!string.IsNullOrEmpty(input.Name), (a, b, c, d) => b.Name.Contains(input.Name))
.WhereIF(!string.IsNullOrEmpty(input.Id), (a, b, c, d) => a.Id.Contains(input.Id))
+ .WhereIF(input.Status != null, (a, b, c, d) => input.Status.Contains(d.Status))
+ .WhereIF(input.StartTime != null, (a, b, c, d) => input.StartTime <= Convert.ToDateTime(a.CreateTime))
+ .WhereIF(input.EndTime != null, (a, b, c, d) => input.EndTime.Value.AddHours(23).AddMinutes(59).AddSeconds(59) >= Convert.ToDateTime(a.CreateTime))
.Select((a, b, c, d) => new WorkInfoOutput
{
Id = a.Id.SelectAll(),
@@ -359,15 +365,30 @@ namespace BPA.MES.Base.Application.Services.WorkInfoService.Services
[HttpPost]
public async Task UpdateWorkCraftStepsStatus(WorkInfoCraftstepRecordUpdateInput input)
{
- WorkInfoCraftstepRecordEntity entity = new()
+
+
+ var entityFrist = await _dbContext.Queryable().Where(x => x.Id == input.WorkCraftstepId).FirstAsync();
+ if (!string.IsNullOrEmpty(input.WorkId))
{
- Id = input.WorkCraftstepId,
- Status = input.Status,
- UpdateTime = DateTime.Now
- };
- bool res = await _dbContext.Updateable(entity).IgnoreColumns(true).ExecuteCommandHasChangeAsync();
- return res;
+ bool res = await _dbContext.Updateable()
+ .SetColumns(x=>x.Status==input.Status)
+ .SetColumns(x=>x.UpdateTime==DateTime.Now).IgnoreColumns(true).Where(x=>x.WorkId==input.WorkId && x.PotNum==input.PotNum).ExecuteCommandHasChangeAsync();
+ return res;
+ }
+ else
+ {
+ WorkInfoCraftstepRecordEntity entity = new()
+ {
+ Id = input.WorkCraftstepId,
+ Status = input.Status,
+ UpdateTime = DateTime.Now,
+ Step = entityFrist.Step
+ };
+ bool res = await _dbContext.Updateable(entity).IgnoreColumns(true).ExecuteCommandHasChangeAsync();
+ return res;
+ }
}
+
///
/// 强制结束工单
///
diff --git a/backend/BPA.MES.Base.Core/BPA.MES.Base.Core.csproj b/backend/BPA.MES.Base.Core/BPA.MES.Base.Core.csproj
index 58e025d..c91d436 100644
--- a/backend/BPA.MES.Base.Core/BPA.MES.Base.Core.csproj
+++ b/backend/BPA.MES.Base.Core/BPA.MES.Base.Core.csproj
@@ -13,6 +13,9 @@
+
+
+
diff --git a/backend/BPA.MES.Base.Web.Core/Startup.cs b/backend/BPA.MES.Base.Web.Core/Startup.cs
index c34c1d9..8cc2834 100644
--- a/backend/BPA.MES.Base.Web.Core/Startup.cs
+++ b/backend/BPA.MES.Base.Web.Core/Startup.cs
@@ -1,11 +1,21 @@
-using BPA.MES.Base.Application;
+using System;
+using System.Threading.Tasks;
+using BPA.AGV;
+using BPA.ApiClient;
+using BPA.MES.Base.Application;
using BPA.MES.Base.Application.Subscriber;
using BPA.MES.Base.Core;
+using BPA.MQTTClient;
using Furion;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+using MQTTnet.Client;
+using MQTTnet.Client.Connecting;
+using MQTTnet.Client.Disconnecting;
+using MQTTnet.Client.Options;
+using Newtonsoft.Json.Linq;
using Yitter.IdGenerator;
namespace BPA.MES.Base.Web.Core;
@@ -14,6 +24,7 @@ public class Startup : AppStartup
{
public void ConfigureServices(IServiceCollection services)
{
+
services.AddConsoleFormatter();
services.AddJwt(enableGlobalAuthorize: true);
services.AddCorsAccessor();
@@ -30,6 +41,50 @@ public class Startup : AppStartup
builder.AddSubscriber(typeof(ToDoEventSubscriber));
});
services.AddRemoteRequest();
+
+ services.AddWebApiClient();
+ services.AddAGV(op =>
+ {
+ op.Header = new KCOption()
+ {
+ AppKey = "43",
+ AppSecret = "12",
+ RequestId = "43",
+ Timestamp = "2234234324",
+ Version = "2.9"
+ };
+ op.Sign = "123456";
+ });
+
+ //services.AddMqttClientHostedService(op =>
+ //{
+ // op.Port = 1883;
+ // op.Server = "10.2.1.21";
+ // op.UserName = "emqx_u_block";
+ // op.Password = "emqx_p_admin8765490789";
+ // op.mqttClientConnectedHandlerDelegate = new MqttClientConnectedHandlerDelegate(async e =>
+ // {
+ // Console.WriteLine("MQTT连接成功");
+ // });
+ // op.mqttClientDisconnectedHandlerDelegate = new MqttClientDisconnectedHandlerDelegate(async e =>
+ // {
+ // Console.WriteLine("MQTT断开连接");
+ // await Task.Delay(TimeSpan.FromSeconds(5));
+ // try
+ // {
+ // //var options = builder.Build().Services.GetService();
+ // //await builder.Build().Services.GetService().ConnectAsync(options);
+ // }
+ // catch (global::System.Exception)
+ // {
+ // }
+ // });
+ // op.MqttApplicationMessageReceivedHandler = new MQTTnet.Client.Receiving.MqttApplicationMessageReceivedHandlerDelegate(async e =>
+ // {
+
+ // });
+ //});
+
services.AddControllers()
.AddInjectWithUnifyResult();
}
diff --git a/frontend/config/proxy.ts b/frontend/config/proxy.ts
index 152426e..6f8a8a0 100644
--- a/frontend/config/proxy.ts
+++ b/frontend/config/proxy.ts
@@ -6,7 +6,7 @@
export default {
dev: {
'/api/': {
- target: 'http://10.2.1.26:21674/api',
+ target: 'http://localhost:5002',
pathRewrite: {
'/api': '/api'
},
diff --git a/frontend/config/routes.ts b/frontend/config/routes.ts
index ee8e89b..3807487 100644
--- a/frontend/config/routes.ts
+++ b/frontend/config/routes.ts
@@ -71,6 +71,7 @@
path: '/report', icon: 'SettingOutlined', name: '统计报表',
routes: [
{ path: '/report/product', name: '成品统计', component: './report/product' },
+ { path: '/report/material', name: '原料统计', component: './report/material' },
]
},
{ path: '*', layout: false, component: './404' },
diff --git a/frontend/src/api/orderService.ts b/frontend/src/api/orderService.ts
index ae48440..0d17f47 100644
--- a/frontend/src/api/orderService.ts
+++ b/frontend/src/api/orderService.ts
@@ -76,6 +76,17 @@ export default {
});
},
+ /**
+ * 获取成品可制造数量
+ * @param parms
+ * @returns
+ */
+ getFinalslLImit(parms:string) {
+ return request('/api/order/getfinalsllimit/'+parms, {
+ method: 'get',
+ });
+ },
+
}
diff --git a/frontend/src/api/reportService.ts b/frontend/src/api/reportService.ts
index 4b51d7e..f77ab36 100644
--- a/frontend/src/api/reportService.ts
+++ b/frontend/src/api/reportService.ts
@@ -8,13 +8,27 @@ export default {
* @param parms
* @returns
*/
- PagedList(parms: ReportType.ProductReportInput) {
+ PagedList(parms: ReportType.ReportInput) {
return request('/api/report/getproductreport', {
method: 'POST',
data: {
...parms,
},
});
+ },
+
+ /**
+ * 获取原料统计
+ * @param parms
+ * @returns
+ */
+ PagedMaterialList(parms: ReportType.ReportInput) {
+ return request('/api/report/getmaterialsreport', {
+ method: 'POST',
+ data: {
+ ...parms,
+ },
+ });
}
}
diff --git a/frontend/src/pages/dict/index.tsx b/frontend/src/pages/dict/index.tsx
index 2c8fe4e..7687cf1 100644
--- a/frontend/src/pages/dict/index.tsx
+++ b/frontend/src/pages/dict/index.tsx
@@ -157,7 +157,7 @@ export default () => {
{
title: '主键',
dataIndex: 'id',
- // hideInTable: true,
+ hideInTable: true,
hideInForm: true,
search: true,
},
@@ -167,9 +167,7 @@ export default () => {
ellipsis: true,
hindeInForm: true,
search: false,
- // hideInTable: true,
-
-
+ hideInTable: true,
},
{
title: '编码',
diff --git a/frontend/src/pages/order/index.tsx b/frontend/src/pages/order/index.tsx
index 9ba5dda..be37db0 100644
--- a/frontend/src/pages/order/index.tsx
+++ b/frontend/src/pages/order/index.tsx
@@ -222,7 +222,7 @@ export default () => {
if (res.data) {
message.success('添加成功');
actionRef.current?.reload();
- setIsModalOpen(false);
+ setIsWorkModalOpen(false);
} else {
message.error(res.errors || '添加失败');
}
@@ -478,7 +478,7 @@ export default () => {
},
]}
>
-