@@ -64,6 +64,10 @@ | |||
/// 是否是管理员 | |||
/// </summary> | |||
public const bool ISADMIN = false; | |||
/// <summary> | |||
/// 所有缓存关键字集合 | |||
/// </summary> | |||
public const string CACHE_KEY_ALL = "allkey"; | |||
} | |||
public class MQTTConfig | |||
@@ -24,6 +24,11 @@ | |||
/// <summary> | |||
/// 原料分组 | |||
/// </summary> | |||
public string Gourp { get; set; } | |||
public string Type { get; set; } | |||
/// <summary> | |||
/// 每升重量 | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public string WeightPerLiter { get; set; } | |||
} | |||
} |
@@ -23,12 +23,17 @@ | |||
/// </summary> | |||
public string FinalId { get; set; } | |||
/// <summary> | |||
/// 指定设备Id | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public string DeviceId { get; set; } | |||
/// <summary> | |||
/// 产量 | |||
/// </summary> | |||
public string Number { get;set; } | |||
/// <summary> | |||
/// 创建时间 | |||
/// </summary> | |||
public string CreateTime { get; set; } | |||
public DateTime CreateTime { get; set; } | |||
} | |||
} |
@@ -21,5 +21,9 @@ | |||
/// 创建时间 | |||
/// </summary> | |||
public DateTime CreateTime { get; set; } | |||
/// <summary> | |||
/// 备注 | |||
/// </summary> | |||
public string Remark { get; set; } | |||
} | |||
} |
@@ -1,23 +0,0 @@ | |||
namespace BPA.MES.Base.Application.Entitys | |||
{ | |||
/// <summary> | |||
/// 名 称 :设备 | |||
/// 创 建 人 :yangxiao | |||
/// 创建时间 :2023/3/2 13:51:45 | |||
/// 描 述 : | |||
/// </summary> | |||
[SugarTable("devices_info")] | |||
public class DevicesInfoEntity: DEntityBase | |||
{ | |||
/// <summary> | |||
/// 名称 | |||
/// </summary> | |||
[Required(ErrorMessage = "名称不能为空")] | |||
public string Name { get; set; } | |||
/// <summary> | |||
/// 编码 | |||
/// </summary> | |||
[Required(ErrorMessage = "编码不能为空")] | |||
public string Code { get; set; } | |||
} | |||
} |
@@ -1,31 +0,0 @@ | |||
namespace BPA.MES.Base.Application.Entitys | |||
{ | |||
/// <summary> | |||
/// 名 称 :物料 | |||
/// 创 建 人 :yangxiao | |||
/// 创建时间 :2023/3/2 13:52:00 | |||
/// 描 述 : | |||
/// </summary> | |||
[SugarTable("materials_info")] | |||
public class MaterialsInfoEntity: DEntityBase | |||
{ | |||
/// <summary> | |||
/// 名称 | |||
/// </summary> | |||
[Required(ErrorMessage = "名称不能为空")] | |||
public string Name { get; set; } | |||
/// <summary> | |||
/// 编码 | |||
/// </summary> | |||
[Required(ErrorMessage = "编码不能为空")] | |||
public string Code { get; set; } | |||
/// <summary> | |||
/// 单位 | |||
/// </summary> | |||
public string Unit { get; set; } | |||
/// <summary> | |||
/// 每秒出水量(g) | |||
/// </summary> | |||
public string Wos { get; set; } | |||
} | |||
} |
@@ -6,7 +6,7 @@ | |||
/// 创建时间 : 2023/8/21 10:17:57 | |||
/// 描 述 : | |||
/// </summary> | |||
[SugarTable("alarm_log")] | |||
[SugarTable("alarm")] | |||
public class AlarmLogEntity : DEntityBase | |||
{ | |||
/// <summary> | |||
@@ -14,23 +14,41 @@ | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public string MsgInfo { get; set; } | |||
/// <summary> | |||
/// 报警值 | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public string Value { get; set; } | |||
/// <summary> | |||
/// 报警等级 | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public string Grade { get; set; } | |||
/// <summary> | |||
/// 设备名称 | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public string DeviceName { get; set; } | |||
/// <summary> | |||
/// 日期 | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public string Date { get; set; } | |||
/// <summary> | |||
/// 时间 | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public string Time { get; set; } | |||
/// <summary> | |||
/// 创建时间 | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public DateTime CreateDate { get; set; } | |||
/// <summary> | |||
/// 类型 | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public string LogType { get; set; } | |||
} | |||
} |
@@ -6,7 +6,7 @@ | |||
/// 创建时间 : 2023/8/21 10:18:13 | |||
/// 描 述 : | |||
/// </summary> | |||
[SugarTable("program_log")] | |||
[SugarTable("programlog")] | |||
public class ProgramLogEntity : DEntityBase | |||
{ | |||
/// <summary> | |||
@@ -20,5 +20,21 @@ | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public string MsgInfo { get; set; } | |||
/// <summary> | |||
/// 日期 | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public string Date { get; set; } | |||
/// <summary> | |||
/// 时间 | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public string Time { get; set; } | |||
/// <summary> | |||
/// 日志消息 | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public DateTime CreateDate { get; set; } | |||
} | |||
} |
@@ -6,7 +6,7 @@ | |||
/// 创建时间 : 2023/8/21 10:18:34 | |||
/// 描 述 : | |||
/// </summary> | |||
[SugarTable("run_log")] | |||
[SugarTable("runlog")] | |||
public class RunLogEntity : DEntityBase | |||
{ | |||
/// <summary> | |||
@@ -14,11 +14,25 @@ | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public string LogType { get; set; } | |||
/// <summary> | |||
/// 日志消息 | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public string MsgInfo { get; set; } | |||
/// <summary> | |||
/// 日期 | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public string Date { get; set; } | |||
/// <summary> | |||
/// 时间 | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public string Time { get; set; } | |||
/// <summary> | |||
/// 日志消息 | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public DateTime CreateDate { get; set; } | |||
} | |||
} |
@@ -26,5 +26,11 @@ | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public string MsgInfo { get; set; } | |||
/// <summary> | |||
/// 日志时间 | |||
/// </summary> | |||
[SugarColumn(IsNullable = true)] | |||
public DateTime CreateDate { get; set; } | |||
} | |||
} |
@@ -0,0 +1,39 @@ | |||
using BPA.MES.Base.Application.Services; | |||
using BPA.MES.Base.Application.Services.AGVService.Dtos; | |||
using Furion.JsonSerialization; | |||
using Microsoft.AspNetCore.Mvc.Filters; | |||
using System.Diagnostics; | |||
namespace BPA.MES.Base.Application | |||
{ | |||
public class AGVAttribute : ActionFilterAttribute | |||
{ | |||
/// <summary> | |||
/// 执行操作前后 | |||
/// </summary> | |||
/// <param name="context"></param> | |||
/// <param name="next"></param> | |||
/// <returns></returns> | |||
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) | |||
{ | |||
// 获取 HttpContext 和 HttpRequest 对象 | |||
var httpContext = context.HttpContext; | |||
var httpRequest = httpContext.Request; | |||
var sw = new Stopwatch(); | |||
sw.Start(); | |||
var actionContext = await next(); | |||
sw.Stop(); | |||
var server = App.GetService<IAGVThirdPartyService>(); | |||
var contentstring = JSON.Serialize(context.ActionArguments["input"]); | |||
AGVLoadAndUnloadRequest input = JSON.Deserialize<AGVLoadAndUnloadRequest>(contentstring); | |||
Roller_JobRequest roller_Job = new() | |||
{ | |||
AgvCode = input.Body.Event.agvCode, | |||
Complete = true, | |||
JobId = input.Body.Event.jobId, | |||
MsgId = input.Body.Event.msgId | |||
}; | |||
await server.RollerJobExecute(roller_Job); | |||
} | |||
} | |||
} |
@@ -11,12 +11,14 @@ namespace BPA.MES.Base.Application | |||
/// 创建时间 : 2022/11/18 15:38:40 | |||
/// 描 述 : | |||
/// </summary> | |||
public class MQTTService : IMQTTService, ITransient | |||
public class MQTTService : IMQTTService, ITransient, IDynamicApiController | |||
{ | |||
private readonly ISqlSugarClient _dbContext; | |||
public MQTTService(ISqlSugarClient db) | |||
ISysCacheService _sysCacheService; | |||
public MQTTService(ISqlSugarClient db, ISysCacheService sysCacheService) | |||
{ | |||
_dbContext = db; | |||
_sysCacheService = sysCacheService; | |||
} | |||
public async Task GetMQTTConfig() | |||
{ | |||
@@ -26,49 +28,90 @@ namespace BPA.MES.Base.Application | |||
MQTTConfig.Address = entity.Address; | |||
MQTTConfig.Account = entity.Account; | |||
MQTTConfig.Pwd = entity.Pwd; | |||
await _sysCacheService.SetAsync("mqtt", entity); | |||
} | |||
} | |||
/// <summary> | |||
/// Mqtt通用服务 | |||
/// </summary> | |||
public async Task<bool> MqttPublish(IMessage payload, string topic,int messageId) | |||
public async Task<bool> MqttPublish(MqttPublishDto input) | |||
{ | |||
bool result = false; | |||
MQTTInfoEntity mqttentity = new(); | |||
mqttentity = await _sysCacheService.GetAsync<MQTTInfoEntity>("mqtt"); | |||
if (mqttentity==null) | |||
{ | |||
mqttentity = await _dbContext.Queryable<MQTTInfoEntity>().FirstAsync(); | |||
await _sysCacheService.SetAsync("mqtt", mqttentity); | |||
} | |||
try | |||
{ | |||
input.Payload.MessageId = input.MessageId; | |||
input.Payload.MsgVersion = new Version(1, 0, 0, 0); | |||
MsgPackage mp = new() | |||
{ | |||
Message = input.Payload, | |||
MessageLen = JSON.Serialize(input.Payload).Length | |||
}; | |||
//组装MQTT消息 | |||
var tem = await $"http://{mqttentity.Address}/api/v5/publish".SetHeaders(new | |||
{ | |||
Authorization = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes($"{mqttentity.Account}:{mqttentity.Pwd}")) | |||
}).SetBody(new | |||
{ | |||
input.Topic, | |||
payload = JsonConvert.SerializeObject(mp), | |||
qos = 2, | |||
retain = false, | |||
clientid = "pztj_service" | |||
}).PostAsStringAsync(); | |||
var res = JSON.Deserialize<MqttResult>(tem); | |||
if (res.Code == 0 || res.Reason_code<100 || !string.IsNullOrEmpty(res.Id)) | |||
{ | |||
result = true; | |||
} | |||
Console.WriteLine($"_____________________MQTT发消息:{JsonConvert.SerializeObject(mp)}"); | |||
} | |||
catch | |||
{ | |||
} | |||
return result; | |||
} | |||
[AllowAnonymous] | |||
public async Task<bool> MqttTestPublish(string topic, string msg) | |||
{ | |||
bool result = false; | |||
var mqttentity = await _dbContext.Queryable<MQTTInfoEntity>().FirstAsync(); | |||
string mqttAddress = mqttentity.Address; | |||
try | |||
{ | |||
payload.MessageId = messageId; | |||
payload.MsgVersion = new Version(1, 0, 0, 0); | |||
MsgPackage mp = new MsgPackage(); | |||
mp.Message = payload; | |||
mp.MessageLen = JSON.Serialize(payload).Length; | |||
//组装MQTT消息 | |||
var tem = await $"http://{mqttAddress}/api/v4/mqtt/publish".SetHeaders(new | |||
var tem = await $"http://{mqttAddress}/api/v5/publish".SetHeaders(new | |||
{ | |||
Authorization = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes($"{mqttentity.Account}:{mqttentity.Pwd}")) | |||
}).SetBody(new | |||
{ | |||
topic, | |||
payload = JsonConvert.SerializeObject(mp), | |||
payload = msg, | |||
qos = 2, | |||
retain = false, | |||
clientid = "pztj_service" | |||
}).PostAsStringAsync(); | |||
var res = JSON.Deserialize<MqttResult>(tem); | |||
if (res.Code == 0) | |||
if (res.Code == 0 || res.Reason_code < 100 || !string.IsNullOrEmpty(res.Id)) | |||
{ | |||
result = true; | |||
} | |||
} | |||
catch | |||
{ | |||
} | |||
return result; | |||
} | |||
} | |||
public class MqttResult | |||
@@ -77,11 +120,25 @@ namespace BPA.MES.Base.Application | |||
/// code | |||
/// </summary> | |||
public int Code { get; set; } | |||
/// <summary> | |||
/// reason_code | |||
/// </summary> | |||
public int Reason_code { get; set; } | |||
/// <summary> | |||
/// | |||
/// </summary> | |||
public string Id { get; set; } | |||
} | |||
public class MqttPublishDto | |||
{ | |||
public IMessage Payload { get; set; } | |||
public string Topic { get; set; } | |||
public int MessageId { get; set; } | |||
} | |||
public interface IMQTTService | |||
{ | |||
Task<bool> MqttPublish(IMessage payload, string topic, int messageId); | |||
Task<bool> MqttPublish(MqttPublishDto input); | |||
Task GetMQTTConfig(); | |||
} | |||
@@ -1,4 +1,5 @@ | |||
using System; | |||
using BPA.AGV; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
@@ -7,10 +8,37 @@ using System.Threading.Tasks; | |||
namespace BPA.MES.Base.Application.Services.AGVService.Dtos | |||
{ | |||
public class Roller_JobRequest | |||
{ | |||
public string Url { get; set; } | |||
[Required(ErrorMessage = "[{0}]不能为空")] | |||
[MaxLength(64, ErrorMessage = "[{0}]不能超过64字符")] | |||
public string AgvCode { get; set; } | |||
[Required(ErrorMessage = "[{0}]不能为空")] | |||
[MaxLength(64, ErrorMessage = "[{0}]不能超过64字符")] | |||
public string JobId { get; set; } | |||
[Required(ErrorMessage = "[{0}]不能为空")] | |||
[MaxLength(64, ErrorMessage = "[{0}]不能超过64字符")] | |||
public string MsgId { get; set; } | |||
public bool? Complete { get; set; } | |||
} | |||
public class AGVExecuteReplyRequest | |||
{ | |||
public AgvHeader Header { get; set; } | |||
public AgvReplyBody Body { get; set; } | |||
} | |||
public class AgvReplyBody | |||
{ | |||
public AGVExecuteReplyDto Event { get; set; } | |||
} | |||
public class AGVExecuteReplyMQTT: IMessage | |||
{ | |||
public AGVExecuteReplyDto Event { get; set; } | |||
@@ -19,6 +47,12 @@ namespace BPA.MES.Base.Application.Services.AGVService.Dtos | |||
} | |||
public class AGVLoadAndUnloadRequest | |||
{ | |||
public AgvHeader Header { get; set; } | |||
public AGVLoadAndUnloadBody Body { get; set; } | |||
} | |||
public class AGVLoadAndUnloadBody | |||
{ | |||
public AGVLoadAndUnloadDto Event { get; set; } | |||
} | |||
@@ -30,6 +64,28 @@ namespace BPA.MES.Base.Application.Services.AGVService.Dtos | |||
public Version MsgVersion { get; set; } | |||
} | |||
public class AgvBody | |||
{ | |||
public AgvHeader Header { get; set; } | |||
public AgvRetrun Body { get; set; } | |||
} | |||
public class AgvHeader | |||
{ | |||
public string RequestId { get; set; } | |||
public string Timestamp { get; set; } | |||
public string Version { get; set; } | |||
} | |||
public class AgvRetrun | |||
{ | |||
public string Code { get; set; } | |||
public bool Success { get; set; } | |||
public string Message { get; set; } | |||
public object? Data { get; set; } | |||
} | |||
/// <summary> | |||
/// 任务完成回报Dto | |||
/// </summary> | |||
@@ -51,7 +107,7 @@ namespace BPA.MES.Base.Application.Services.AGVService.Dtos | |||
public string jobId { get; set; } | |||
/// <summary> | |||
/// | |||
/// 任务状态 | |||
/// </summary> | |||
public string state { get; set; } | |||
@@ -275,4 +331,143 @@ namespace BPA.MES.Base.Application.Services.AGVService.Dtos | |||
POINT_ROLLER_MOVE=2 | |||
} | |||
public class KC_Response | |||
{ | |||
public KC_Response() | |||
{ | |||
Data = new(); | |||
} | |||
/// <summary> | |||
/// 是否成功 | |||
/// </summary> | |||
public bool Success { get; set; } | |||
/// <summary> | |||
/// 状态码 | |||
/// </summary> | |||
public string Code { get; set; } | |||
/// <summary> | |||
/// 消息 | |||
/// </summary> | |||
public string Message { get; set; } | |||
/// <summary> | |||
/// 返回数据数组 | |||
/// </summary> | |||
public List<KC_Response_Data> Data { get; set; } | |||
} | |||
public class KC_Response_Data | |||
{ | |||
/// <summary> | |||
/// 状态码 | |||
/// </summary> | |||
public string Code { get; set; } | |||
/// <summary> | |||
/// 消息体 | |||
/// </summary> | |||
public string Message { get; set; } | |||
/// <summary> | |||
/// 任务编号 | |||
/// </summary> | |||
public string RobotJobId { get; set; } | |||
} | |||
/// <summary> | |||
/// AGV请求 | |||
/// </summary> | |||
public class KC_ExecuteRequest | |||
{ | |||
/// <summary> | |||
/// 快仓api地址 | |||
/// </summary> | |||
public string Url { get; set; } | |||
/// <summary> | |||
/// 任务编码 | |||
/// </summary> | |||
public string RobotJobId { get; set; } | |||
/// <summary> | |||
/// 仓库编码 默认值1 | |||
/// </summary> | |||
public long WarehouseId { get; set; } = 1; | |||
public string RobotJobGroupId { get; set; } | |||
public int? Sequence { get; set; } | |||
public string RobotJobGroupNum { get; set; } | |||
/// <summary> | |||
/// 优先级 0-99 越高越先执行 | |||
/// </summary> | |||
public int? JobPriority { get; set; } | |||
public int? JobPriorityType { get; set; } | |||
public string Deadline { get; set; } | |||
public string AgvType { get; set; } | |||
public string AgvEndPoint { get; set; } | |||
public bool NeedOperation { get; set; } | |||
public string AgvCode { get; set; } | |||
public int? TaskCountDown { get; set; } = 0; | |||
public string BusinessType { get; set; } | |||
[Required(ErrorMessage = "[{0}]不能为空")] | |||
[MaxLength(64, ErrorMessage = "[{0}]不能超过64字符")] | |||
//任务类型 用来滚筒点对点 POINT_ROLLER_MOVE n8H7jX | |||
public string JobType { get; set; } = "POINT_ROLLER_MOVE"; | |||
[Required(ErrorMessage = "[{0}]不能为空")] | |||
public KC_JobDataRequest? JobData { get; set; } | |||
} | |||
/// <summary> | |||
/// 任务下发起止点信息 | |||
/// </summary> | |||
public class KC_JobDataRequest | |||
{ | |||
/// <summary> | |||
/// 用户自定义信息编号 | |||
/// </summary> | |||
public string ContainerCode { get; set; } | |||
/// <summary> | |||
/// 起点点位 | |||
/// </summary> | |||
[Required(ErrorMessage = "[{0}]不能为空")] | |||
[MaxLength(64, ErrorMessage = "[{0}]不能超过64字符")] | |||
public string StartPoint { get; set; } | |||
/// <summary> | |||
/// 终点点位 | |||
/// </summary> | |||
[Required(ErrorMessage = "[{0}]不能为空")] | |||
[MaxLength(64, ErrorMessage = "[{0}]不能超过64字符")] | |||
public string EndPoint { get; set; } | |||
/// <summary> | |||
/// 上料方式 自动/人工 | |||
/// </summary> | |||
public bool? AutoLoad { get; set; } | |||
/// <summary> | |||
/// 上料交互方式 //接口对接 false | |||
/// </summary> | |||
public bool? EnableIOLoad { get; set; } = false; | |||
/// <summary> | |||
/// 下料方式 true自动/false人工 | |||
/// </summary> | |||
public bool? AutoUnload { get; set; } | |||
/// <summary> | |||
/// 接口对接 false | |||
/// </summary> | |||
public bool? EnableIOUnload { get; set; } = false; | |||
/// <summary> | |||
/// 起点设备ID | |||
/// </summary> | |||
public long LoadEquipmentId { get; set; } | |||
/// <summary> | |||
/// 目标设备ID | |||
/// </summary> | |||
public long UnloadEquipmentId { get; set; } | |||
public long LoadInteractive { get; set; } | |||
public long LoadHeight { get; set; } | |||
public long UnloadHeight { get; set; } | |||
} | |||
} |
@@ -1,24 +1,21 @@ | |||
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; | |||
using Furion.EventBus; | |||
using Furion.JsonSerialization; | |||
using Furion.RemoteRequest.Extensions; | |||
namespace BPA.MES.Base.Application.Services.AGVService.Services | |||
namespace BPA.MES.Base.Application.Services | |||
{ | |||
/// <summary> | |||
/// AGV第三方api | |||
/// </summary> | |||
[AllowAnonymous, NonUnify] | |||
[ApiDescriptionSettings("AGV管理", Name = "AgvThirdParty", Tag = "AGV第三方api", KeepName = true, SplitCamelCase = true, KeepVerb = true)] | |||
public class AGVThirdPartyService:IAGVThirdPartyService, ITransient, IDynamicApiController | |||
public class AGVThirdPartyService : IAGVThirdPartyService, ITransient, IDynamicApiController | |||
{ | |||
private readonly AGVHandler _aGVHandler; | |||
private readonly IMQTTService _MQTTService; | |||
public AGVThirdPartyService(AGVHandler aGVHandler, IMQTTService MQTTService) | |||
public AGVThirdPartyService(AGVHandler aGVHandler, IMQTTService MQTTService) | |||
{ | |||
_aGVHandler = aGVHandler; | |||
_MQTTService = MQTTService; | |||
@@ -27,98 +24,147 @@ namespace BPA.MES.Base.Application.Services.AGVService.Services | |||
/// <summary> | |||
/// 下发任务 | |||
/// </summary> | |||
/// <param name="cExecuteRequest"></param> | |||
/// <param name="input"></param> | |||
/// <returns></returns> | |||
[HttpPost] | |||
public async Task<KCResponse> ExecuteAsync(KCExecuteRequest cExecuteRequest) | |||
public async Task<KC_Response> Execute(KC_ExecuteRequest input) | |||
{ | |||
if (cExecuteRequest.JobData != null) | |||
cExecuteRequest = new KCExecuteRequest | |||
List<KC_ExecuteRequest> cExecuteRequests = new(); | |||
if (string.IsNullOrEmpty(input.RobotJobId)) | |||
{ | |||
throw Oops.Bah("任务编号不能为空"); | |||
} | |||
if (input.JobData != null) | |||
input = new KC_ExecuteRequest | |||
{ | |||
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 | |||
Url = string.IsNullOrEmpty(input.Url) ? App.GetConfig<string>("AGVUrl")+"/api/quicktron/wcs/standardized.robot.job.submit": input.Url + "/api/quicktron/wcs/standardized.robot.job.submit", | |||
RobotJobId = input.RobotJobId,//任务号 | |||
WarehouseId = input.WarehouseId,//仓库编码 默认值1 | |||
JobPriority = input.JobPriority, //优先级 0-99 越高越先执行 | |||
JobPriorityType = input.JobPriorityType, //优先级类型 0 普通和1 强制. | |||
JobType = input.JobType,//任务类型 用来滚筒点对点 POINT_ROLLER_MOVE n8H7jX | |||
JobData = new KC_JobDataRequest | |||
{ | |||
StartPoint = cExecuteRequest.JobData.StartPoint, | |||
EndPoint = cExecuteRequest.JobData.EndPoint, | |||
StartPoint = input.JobData.StartPoint, //起点 | |||
EndPoint = input.JobData.EndPoint,//终点 | |||
ContainerCode = input.JobData.ContainerCode,//桶号 | |||
AutoLoad = input.JobData.AutoLoad,//上料方式 自动/人工 | |||
EnableIOLoad = input.JobData.EnableIOLoad,//上料交互方式 //接口对接 false | |||
AutoUnload = input.JobData.AutoUnload,//下料方式 true自动/false人工 | |||
EnableIOUnload = input.JobData.EnableIOUnload,//接口对接 false | |||
LoadEquipmentId = input.JobData.LoadEquipmentId,//起点设备ID | |||
UnloadEquipmentId = input.JobData.UnloadEquipmentId,//目标设备ID | |||
} | |||
}; | |||
return await _aGVHandler.ExecuteAsync(cExecuteRequest); | |||
cExecuteRequests.Add(input); | |||
try | |||
{ | |||
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}:{input.RobotJobId}接收到下发任务!"); | |||
var res = await input.Url.SetBody(cExecuteRequests).PostAsStringAsync(); | |||
return JSON.Deserialize<KC_Response>(res); | |||
} | |||
catch (Exception ex) | |||
{ | |||
throw Oops.Bah(ex.Message); | |||
} | |||
} | |||
/// <summary> | |||
/// 取消任务 | |||
/// </summary> | |||
/// <param name="kCCancelRequest"></param> | |||
/// <returns></returns> | |||
[HttpPost] | |||
public async Task<KCResponse> CancelAsync(KCCancelRequest kCCancelRequest) | |||
public async Task<KCResponse> Cancel(KCCancelRequest kCCancelRequest) | |||
{ | |||
//http://[IP:Port]/api/quicktron/wcs/standardized.robot.job.cancel | |||
kCCancelRequest.Url = string.IsNullOrEmpty(kCCancelRequest.Url) ? App.GetConfig<string>("AGVUrl") + "/api/quicktron/wcs/standardized.robot.job.cancel" : kCCancelRequest.Url + "/api/quicktron/wcs/standardized.robot.job.cancel"; | |||
return await _aGVHandler.CancelAsync(kCCancelRequest); | |||
} | |||
/// <summary> | |||
/// | |||
/// 上下料反馈给AGV接口 | |||
/// </summary> | |||
/// <param name="rollerJobRequest"></param> | |||
/// <param name="input"></param> | |||
/// <returns></returns> | |||
public async Task<RollerJobResponse> RollerJobExecuteAsync(RollerJobRequest rollerJobRequest) | |||
public async Task<RollerJobResponse> RollerJobExecute(Roller_JobRequest input) | |||
{ | |||
//http://[IP:Port]/api/quicktron/wcs/standardized.roller.job.upstream.response | |||
return await _aGVHandler.RollerJobExecuteAsync(rollerJobRequest); | |||
input.Url = string.IsNullOrEmpty(input.Url) ? App.GetConfig<string>("AGVUrl") + "/api/quicktron/wcs/standardized.roller.job.upstream.response": input.Url+ "/api/quicktron/wcs/standardized.roller.job.upstream.response"; | |||
try | |||
{ | |||
var res = await input.Url.SetBody(input).PostAsStringAsync(); | |||
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}:{input.JobId}上下料反馈给AGV接口!{res}"); | |||
return JSON.Deserialize<RollerJobResponse>(res); | |||
} | |||
catch (Exception ex) | |||
{ | |||
return new RollerJobResponse() { Success = false }; | |||
} | |||
} | |||
/// <summary> | |||
/// 任务回调 | |||
/// 任务反馈(暴露给AGV厂商) | |||
/// </summary> | |||
/// <param name="input"></param> | |||
/// <returns></returns> | |||
[HttpPost] | |||
public async Task<bool> ExecuteReplyAsync(AGVExecuteReplyRequest input) | |||
public async Task<AgvBody> ExecuteReply(AGVExecuteReplyRequest input) | |||
{ | |||
try | |||
{ | |||
var data = new AGVExecuteReplyMQTT() | |||
{ | |||
Event = input.Event, | |||
Event = input.Body.Event, | |||
}; | |||
return await _MQTTService.MqttPublish(data, Topics.ExecuteReplyTopic, MessageID.TaskState); | |||
bool res = await _MQTTService.MqttPublish(new MqttPublishDto(){ Payload= data, Topic = Topics.ExecuteReplyTopic, MessageId = MessageID.TaskState }); | |||
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}:接收到AGV反馈请求!", res.ToString()); | |||
AgvBody agvBody = new() | |||
{ | |||
Header = input.Header, | |||
Body = new AgvRetrun { Code = "SUCCESS", Success = res, Message = "SUCCESS", Data = null } | |||
}; | |||
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}:AGV反馈消息!{JSON.Serialize(agvBody)}"); | |||
return agvBody; | |||
} | |||
catch (Exception e) | |||
catch (Exception ex) | |||
{ | |||
return false; | |||
AgvBody agvBody = new() | |||
{ | |||
Header = input.Header, | |||
Body = new AgvRetrun { Code = "SUCCESS", Success = false, Message = ex.Message, Data = null } | |||
}; | |||
return agvBody; | |||
} | |||
} | |||
/// <summary> | |||
/// AGV上下料交互请求 | |||
/// AGV上下料交互请求 (暴露给AGV厂商) | |||
/// </summary> | |||
/// <param name="input"></param> | |||
/// <returns></returns> | |||
[HttpPost] | |||
public async Task<bool> LoadAndUnloadAsync(AGVLoadAndUnloadRequest input) | |||
[HttpPost, AGV] | |||
public async Task<AgvBody> LoadAndUnload(AGVLoadAndUnloadRequest input) | |||
{ | |||
try | |||
{ | |||
var data = new AGVLoadAndUnloadMQTT() | |||
{ | |||
Event = input.Event, | |||
Event = input.Body.Event, | |||
}; | |||
bool res = await _MQTTService.MqttPublish(new MqttPublishDto() { Payload= data, Topic = Topics.LoadAndUnloadTopic, MessageId = MessageID.LoadAndUnload }); | |||
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}:接收到AGV上下料交互请求!{res.ToString()}"); | |||
AgvBody agvBody = new() | |||
{ | |||
Header = input.Header, | |||
Body = new AgvRetrun { Code = "SUCCESS", Success = res, Message = "SUCCESS", Data = null } | |||
}; | |||
return await _MQTTService.MqttPublish(data, Topics.LoadAndUnloadTopic, MessageID.LoadAndUnload); | |||
return agvBody; | |||
} | |||
catch (Exception e) | |||
catch (Exception ex) | |||
{ | |||
return false; | |||
AgvBody agvBody = new() | |||
{ | |||
Header = input.Header, | |||
Body = new AgvRetrun { Code = "SUCCESS", Success = false, Message = ex.Message, Data = null } | |||
}; | |||
return agvBody; | |||
} | |||
} | |||
} | |||
} |
@@ -1,12 +1,7 @@ | |||
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 | |||
namespace BPA.MES.Base.Application.Services | |||
{ | |||
public interface IAGVThirdPartyService | |||
{ | |||
@@ -14,31 +9,32 @@ namespace BPA.MES.Base.Application.Services.AGVService.Services | |||
/// <summary> | |||
/// 下发任务 | |||
/// </summary> | |||
/// <param name="cExecuteRequest"></param> | |||
/// <param name="input"></param> | |||
/// <returns></returns> | |||
Task<KCResponse> ExecuteAsync(KCExecuteRequest cExecuteRequest); | |||
Task<KC_Response> Execute(KC_ExecuteRequest input); | |||
/// <summary> | |||
/// 取消任务 | |||
/// </summary> | |||
/// <param name="kCCancelRequest"></param> | |||
/// <returns></returns> | |||
Task<KCResponse> CancelAsync(KCCancelRequest kCCancelRequest); | |||
Task<KCResponse> Cancel(KCCancelRequest kCCancelRequest); | |||
/// <summary> | |||
/// 任务回调 | |||
/// </summary> | |||
/// <param name="input"></param> | |||
/// <returns></returns> | |||
Task<bool> ExecuteReplyAsync(AGVExecuteReplyRequest input); | |||
Task<AgvBody> ExecuteReply(AGVExecuteReplyRequest input); | |||
/// <summary> | |||
/// AGV上下料交互请求 | |||
/// </summary> | |||
/// <param name="input"></param> | |||
/// <returns></returns> | |||
Task<bool> LoadAndUnloadAsync(AGVLoadAndUnloadRequest input); | |||
Task<AgvBody> LoadAndUnload(AGVLoadAndUnloadRequest input); | |||
/// <summary> | |||
/// 上下料反馈给AGV接口 | |||
/// </summary> | |||
/// <param name="input"></param> | |||
/// <returns></returns> | |||
Task<RollerJobResponse> RollerJobExecute(Roller_JobRequest input); | |||
} | |||
} |
@@ -39,8 +39,20 @@ | |||
[HttpPost] | |||
public async Task<bool> Del(CraftsInfoDelInput input) | |||
{ | |||
var res = await _dbContext.Deleteable<Pztj_CraftsInfoEntity>().Where(x=>x.Id==input.Id).ExecuteCommandHasChangeAsync(); | |||
return res; | |||
//事务,删除所有子表 | |||
try | |||
{ | |||
_dbContext.Ado.BeginTran(); | |||
await _dbContext.Deleteable<Pztj_CraftsInfoEntity>().Where(x => x.Id == input.Id).ExecuteCommandAsync(); | |||
await _dbContext.Deleteable<Pztj_CraftStepsEntity>().Where(x => x.CraftId == input.Id).ExecuteCommandAsync(); | |||
_dbContext.Ado.CommitTran(); | |||
} | |||
catch (Exception ex) | |||
{ | |||
_dbContext.Ado.RollbackTran(); | |||
throw Oops.Bah("删除失败!"); | |||
} | |||
return true; | |||
} | |||
/// <summary> | |||
/// 详情 | |||
@@ -22,7 +22,7 @@ | |||
[HttpPost] | |||
public async Task<bool> Add(DeviceProductFunctionAddInput input) | |||
{ | |||
var r_entity = await _dbContext.Queryable<DeviceProductFunctionEntity>().FirstAsync(x => x.Name == input.Name); | |||
var r_entity = await _dbContext.Queryable<DeviceProductFunctionEntity>().Where(x=>x.DeviceProductId==input.DeviceProductId && x.Name == input.Name).FirstAsync(); | |||
if (r_entity != null) | |||
{ | |||
throw Oops.Bah("名称已存在!"); | |||
@@ -111,8 +111,16 @@ | |||
[HttpPost] | |||
public async Task<bool> Update(DeviceProductFunctionUpdateInput input) | |||
{ | |||
var isEntity = await _dbContext.Queryable<DeviceProductFunctionEntity>() | |||
.Where(x =>x.Id != input.Id && x.DeviceProductId == input.DeviceProductId && x.Name == input.Name).FirstAsync(); | |||
if (isEntity != null) | |||
{ | |||
throw Oops.Bah("名称已存在!"); | |||
} | |||
var entity = await _dbContext.Queryable<DeviceProductFunctionEntity>().Where(x => x.Id == input.Id).FirstAsync(); | |||
entity = input.Adapt<DeviceProductFunctionEntity>(); | |||
var res = await _dbContext.Updateable(entity).IgnoreColumns(true).ExecuteCommandHasChangeAsync(); | |||
return res; | |||
} | |||
@@ -39,8 +39,20 @@ | |||
[HttpPost] | |||
public async Task<bool> Del(DeviceProductDelInput input) | |||
{ | |||
var res = await _dbContext.Deleteable<DeviceProductEntity>().Where(x => x.Id == input.Id).ExecuteCommandHasChangeAsync(); | |||
return res; | |||
//事务,删除所有子表 | |||
try | |||
{ | |||
_dbContext.Ado.BeginTran(); | |||
await _dbContext.Deleteable<DeviceProductEntity>().Where(x => x.Id == input.Id).ExecuteCommandAsync(); | |||
await _dbContext.Deleteable<DeviceProductFunctionEntity>().Where(x => x.DeviceProductId == input.Id).ExecuteCommandAsync(); | |||
_dbContext.Ado.CommitTran(); | |||
} | |||
catch (Exception ex) | |||
{ | |||
_dbContext.Ado.RollbackTran(); | |||
throw Oops.Bah("删除失败!"); | |||
} | |||
return true; | |||
} | |||
/// <summary> | |||
/// 详情 | |||
@@ -12,21 +12,35 @@ | |||
/// 报警信息 | |||
/// </summary> | |||
public string MsgInfo { get; set; } | |||
/// <summary> | |||
/// 报警值 | |||
/// </summary> | |||
public string Value { get; set; } | |||
/// <summary> | |||
/// 报警等级 | |||
/// </summary> | |||
public string Grade { get; set; } | |||
/// <summary> | |||
/// 类型 | |||
/// </summary> | |||
public string LogType { get; set; } | |||
/// <summary> | |||
/// 设备名称 | |||
/// </summary> | |||
public string DeviceName { get; set; } | |||
/// <summary> | |||
/// 日期 | |||
/// </summary> | |||
public string Date { get; set; } | |||
/// <summary> | |||
/// 时间 | |||
/// </summary> | |||
public string Time { get; set; } | |||
/// <summary> | |||
/// 日志消息 | |||
/// </summary> | |||
public DateTime CreateDate { get; set; } | |||
} | |||
/// <summary> | |||
/// 增加 | |||
@@ -86,6 +100,14 @@ | |||
/// 设备名称 | |||
/// </summary> | |||
public string DeviceName { get; set; } | |||
/// <summary> | |||
/// 开始时间 | |||
/// </summary> | |||
public DateTime? StartTime { get; set; } | |||
/// <summary> | |||
/// 结束时间 | |||
/// </summary> | |||
public DateTime? EndTime { get; set; } | |||
} | |||
/// <summary> | |||
/// 输出 | |||
@@ -17,6 +17,18 @@ | |||
/// 日志消息 | |||
/// </summary> | |||
public string MsgInfo { get; set; } | |||
/// <summary> | |||
/// 日期 | |||
/// </summary> | |||
public string Date { get; set; } | |||
/// <summary> | |||
/// 时间 | |||
/// </summary> | |||
public string Time { get; set; } | |||
/// <summary> | |||
/// 日志消息 | |||
/// </summary> | |||
public DateTime CreateDate { get; set; } | |||
} | |||
/// <summary> | |||
/// 增加 | |||
@@ -66,6 +78,14 @@ | |||
/// 日志消息 | |||
/// </summary> | |||
public string MsgInfo { get; set; } | |||
/// <summary> | |||
/// 开始时间 | |||
/// </summary> | |||
public DateTime? StartTime { get; set; } | |||
/// <summary> | |||
/// 结束时间 | |||
/// </summary> | |||
public DateTime? EndTime { get; set; } | |||
} | |||
/// <summary> | |||
/// 输出 | |||
@@ -12,11 +12,22 @@ | |||
/// 日志类别 | |||
/// </summary> | |||
public string LogType { get; set; } | |||
/// <summary> | |||
/// 日志消息 | |||
/// </summary> | |||
public string MsgInfo { get; set; } | |||
/// <summary> | |||
/// 日期 | |||
/// </summary> | |||
public string Date { get; set; } | |||
/// <summary> | |||
/// 时间 | |||
/// </summary> | |||
public string Time { get; set; } | |||
/// <summary> | |||
/// 日志消息 | |||
/// </summary> | |||
public DateTime CreateDate { get; set; } | |||
} | |||
/// <summary> | |||
/// 增加 | |||
@@ -61,11 +72,18 @@ | |||
/// 日志类别 | |||
/// </summary> | |||
public string LogType { get; set; } | |||
/// <summary> | |||
/// 日志消息 | |||
/// </summary> | |||
public string MsgInfo { get; set; } | |||
/// <summary> | |||
/// 开始时间 | |||
/// </summary> | |||
public DateTime? StartTime { get; set; } | |||
/// <summary> | |||
/// 结束时间 | |||
/// </summary> | |||
public DateTime? EndTime { get; set; } | |||
} | |||
/// <summary> | |||
/// 输出 | |||
@@ -22,6 +22,10 @@ | |||
/// 日志消息 | |||
/// </summary> | |||
public string MsgInfo { get; set; } | |||
/// <summary> | |||
/// 日志时间 | |||
/// </summary> | |||
public DateTime CreateDate { get; set; } | |||
} | |||
/// <summary> | |||
/// 增加 | |||
@@ -75,6 +75,9 @@ | |||
.WhereIF(!string.IsNullOrEmpty(input.Grade), x => x.Grade.Contains(input.Grade)) | |||
.WhereIF(!string.IsNullOrEmpty(input.MsgInfo), x => x.MsgInfo.Contains(input.MsgInfo)) | |||
.WhereIF(!string.IsNullOrEmpty(input.Value), x => x.Value.Contains(input.Value)) | |||
.WhereIF(input.StartTime.HasVal(), x => x.CreateDate >= input.StartTime.Value) | |||
.WhereIF(input.EndTime.HasVal(), x => x.CreateDate <= input.EndTime.Value) | |||
.OrderByDescending(x=>x.CreateDate) | |||
.ToPagedListAsync(input.PageIndex, input.PageSize); | |||
SqlSugarPagedList<AlarmLogOutput> output = entity.Adapt<SqlSugarPagedList<AlarmLogOutput>>(); | |||
return output; | |||
@@ -73,6 +73,9 @@ | |||
var entity = await _dbContext.Queryable<ProgramLogEntity>() | |||
.WhereIF(input.LogType != null, x => x.LogType == input.LogType) | |||
.WhereIF(!string.IsNullOrEmpty(input.MsgInfo), x => x.MsgInfo.Contains(input.MsgInfo)) | |||
.WhereIF(input.StartTime.HasVal(), x => x.CreateDate >= input.StartTime.Value) | |||
.WhereIF(input.EndTime.HasVal(), x => x.CreateDate <= input.EndTime.Value) | |||
.OrderByDescending(x => x.CreateDate) | |||
.ToPagedListAsync(input.PageIndex, input.PageSize); | |||
SqlSugarPagedList<ProgramLogOutput> output = entity.Adapt<SqlSugarPagedList<ProgramLogOutput>>(); | |||
return output; | |||
@@ -73,6 +73,9 @@ | |||
var entity = await _dbContext.Queryable<RunLogEntity>() | |||
.WhereIF(!string.IsNullOrEmpty(input.LogType), x => x.LogType.Contains(input.LogType)) | |||
.WhereIF(!string.IsNullOrEmpty(input.MsgInfo), x => x.MsgInfo.Contains(input.MsgInfo)) | |||
.WhereIF(input.StartTime.HasVal(), x => x.CreateDate >= input.StartTime.Value) | |||
.WhereIF(input.EndTime.HasVal(), x => x.CreateDate <= input.EndTime.Value) | |||
.OrderByDescending(x => x.CreateDate) | |||
.ToPagedListAsync(input.PageIndex, input.PageSize); | |||
SqlSugarPagedList<RunLogOutput> output = entity.Adapt<SqlSugarPagedList<RunLogOutput>>(); | |||
return output; | |||
@@ -27,7 +27,12 @@ | |||
/// 原料分组 | |||
/// </summary> | |||
/// <example></example> | |||
public string Gourp { get; set; } | |||
public string Type { get; set; } | |||
/// <summary> | |||
/// 每升重量 | |||
/// </summary> | |||
public string WeightPerLiter { get; set; } | |||
} | |||
/// <summary> | |||
/// 增加 | |||
@@ -84,5 +89,9 @@ | |||
/// </summary> | |||
/// <example></example> | |||
public string Id { get; set; } | |||
/// <summary> | |||
/// 类型名称 | |||
/// </summary> | |||
public string TypeName { get; set; } | |||
} | |||
} |
@@ -51,8 +51,15 @@ | |||
[HttpGet] | |||
public async Task<MaterialsInfoOutput> Detail(string Id) | |||
{ | |||
var entity = await _dbContext.Queryable<Pztj_MaterialsInfoEntity>().FirstAsync(x => x.Id == Id); | |||
MaterialsInfoOutput output = entity.Adapt<MaterialsInfoOutput>(); | |||
var output = await _dbContext.Queryable<Pztj_MaterialsInfoEntity>() | |||
.LeftJoin<DictDataEntity>((a,b)=>a.Type==b.Id) | |||
.Where((a,b)=> a.Id == Id) | |||
.Select((a,b)=>new MaterialsInfoOutput | |||
{ | |||
Id=a.Id.SelectAll(), | |||
TypeName = b.Value | |||
}) | |||
.FirstAsync(); | |||
return output; | |||
} | |||
/// <summary> | |||
@@ -63,8 +70,14 @@ | |||
[HttpGet] | |||
public async Task<List<MaterialsInfoOutput>> List() | |||
{ | |||
var entity = await _dbContext.Queryable<Pztj_MaterialsInfoEntity>().ToListAsync(); | |||
List<MaterialsInfoOutput> output = entity.Adapt<List<MaterialsInfoOutput>>(); | |||
var output = await _dbContext.Queryable<Pztj_MaterialsInfoEntity>() | |||
.LeftJoin<DictDataEntity>((a, b) => a.Type == b.Id) | |||
.Select((a, b) => new MaterialsInfoOutput | |||
{ | |||
Id = a.Id.SelectAll(), | |||
TypeName = b.Value | |||
}) | |||
.ToListAsync(); | |||
return output; | |||
} | |||
/// <summary> | |||
@@ -75,11 +88,16 @@ | |||
[HttpPost] | |||
public async Task<SqlSugarPagedList<MaterialsInfoOutput>> PagedList(MaterialsInfoQueryPageInput input) | |||
{ | |||
var entity = await _dbContext.Queryable<Pztj_MaterialsInfoEntity>() | |||
.WhereIF(!string.IsNullOrEmpty(input.Name),x=>x.Name.Contains(input.Name)) | |||
.WhereIF(!string.IsNullOrEmpty(input.Code), x => x.Code.Contains(input.Code)) | |||
var output = await _dbContext.Queryable<Pztj_MaterialsInfoEntity>() | |||
.LeftJoin<DictDataEntity>((a, b) => a.Type == b.Id) | |||
.WhereIF(!string.IsNullOrEmpty(input.Name), (a, b) => a.Name.Contains(input.Name)) | |||
.WhereIF(!string.IsNullOrEmpty(input.Code), (a, b) => a.Code.Contains(input.Code)) | |||
.Select((a, b) => new MaterialsInfoOutput | |||
{ | |||
Id = a.Id.SelectAll(), | |||
TypeName = b.Value | |||
}) | |||
.ToPagedListAsync(input.PageIndex, input.PageSize); | |||
SqlSugarPagedList<MaterialsInfoOutput> output = entity.Adapt<SqlSugarPagedList<MaterialsInfoOutput>>(); | |||
return output; | |||
} | |||
/// <summary> | |||
@@ -58,7 +58,7 @@ namespace BPA.MES.Base.Application.Services.OrderService.Service | |||
ProductionLineId=a.LineId, | |||
ProductionLineName=c.Name, | |||
Id = a.Id, | |||
CreateTime=a.CreateTime, | |||
CreateTime=a.CreateTime.ToString(), | |||
Status = d.Status == null ? WorkOrderStatusEnum.Draft : d.Status | |||
}).ToListAsync(); | |||
@@ -230,7 +230,7 @@ namespace BPA.MES.Base.Application.Services.OrderService.Service | |||
{ | |||
Pztj_WorkInfoEntity entity = new Pztj_WorkInfoEntity() | |||
{ | |||
CreateTime = DateTime.Now.ToString(), | |||
CreateTime = DateTime.Now, | |||
FinalId = item.FinalslId, | |||
LineId = item.ProductionLineId, | |||
Name = "", | |||
@@ -20,6 +20,20 @@ | |||
public class ProductLineDeviceAddInput: ProductLineDeviceDto { | |||
} | |||
/// <summary> | |||
/// 产线设备不分页 | |||
/// </summary> | |||
public class ProductLineDeviceQueryInput | |||
{ | |||
/// <summary> | |||
/// 名称 | |||
/// </summary> | |||
public string Name { get; set; } | |||
/// <summary> | |||
/// 产线Id | |||
/// </summary> | |||
public string LineId { get; set; } | |||
} | |||
/// <summary> | |||
/// 产线设备分页 | |||
@@ -21,6 +21,24 @@ | |||
{ | |||
} | |||
/// <summary> | |||
/// 产线设备不分页 | |||
/// </summary> | |||
public class ProductLineStockQueryInput | |||
{ | |||
/// <summary> | |||
/// 名称 | |||
/// </summary> | |||
public string Name { get; set; } | |||
/// <summary> | |||
/// 产线Id | |||
/// </summary> | |||
public string LineId { get; set; } | |||
/// <summary> | |||
/// 物料Id | |||
/// </summary> | |||
public string MaterialId { get; set; } | |||
} | |||
/// <summary> | |||
/// 产线设备分页 | |||
@@ -56,6 +74,10 @@ | |||
/// </summary> | |||
public string Id { get; set; } | |||
/// <summary> | |||
/// 产线名称 | |||
/// </summary> | |||
public string LineName { get; set; } | |||
/// <summary> | |||
/// 名称 | |||
/// </summary> | |||
/// <example>设备名称</example> | |||
@@ -64,6 +86,14 @@ | |||
/// 编码 | |||
/// </summary> | |||
public string StockCode { get; set; } | |||
/// <summary> | |||
/// 物料信息 | |||
/// </summary> | |||
public string MaterialId { get; set; } | |||
/// <summary> | |||
/// 物料名称 | |||
/// </summary> | |||
public string MateriaName { get; set; } | |||
} | |||
} | |||
@@ -63,7 +63,7 @@ | |||
/// 产线设备不分页 | |||
/// </summary> | |||
/// <returns></returns> | |||
Task<List<ProductLineDeviceOutput>> DeviceList(); | |||
Task<List<ProductLineDeviceOutput>> DeviceList(ProductLineDeviceQueryInput input); | |||
/// <summary> | |||
/// 产线设备分页 | |||
/// </summary> | |||
@@ -90,7 +90,7 @@ | |||
/// 产线料仓不分页 | |||
/// </summary> | |||
/// <returns></returns> | |||
Task<List<ProductLineStockOutput>> StockList(); | |||
Task<List<ProductLineStockOutput>> StockList(ProductLineStockQueryInput input); | |||
/// <summary> | |||
/// 产线料仓分页 | |||
/// </summary> | |||
@@ -145,11 +145,24 @@ | |||
/// 产线设备不分页 | |||
/// </summary> | |||
/// <returns></returns> | |||
[HttpGet] | |||
public async Task<List<ProductLineDeviceOutput>> DeviceList() | |||
[HttpPost] | |||
public async Task<List<ProductLineDeviceOutput>> DeviceList(ProductLineDeviceQueryInput input) | |||
{ | |||
var entity = await _dbContext.Queryable<Pztj_LineDevicesEntity>().ToListAsync(); | |||
List<ProductLineDeviceOutput> output = entity.Adapt<List<ProductLineDeviceOutput>>(); | |||
var output = await _dbContext.Queryable<Pztj_LineDevicesEntity>() | |||
.LeftJoin<Pztj_DevicesInfoEntity>((a, b) => a.DeviceId == b.Id) | |||
.WhereIF(!string.IsNullOrEmpty(input.Name), (a, b) => b.Name.Contains(input.Name)) | |||
.WhereIF(!string.IsNullOrEmpty(input.LineId), (a, b) => a.LineId == input.LineId) | |||
.Select((a, b) => new ProductLineDeviceOutput | |||
{ | |||
DeviceId = a.DeviceId, | |||
DeviceCode = b.Code, | |||
DeviceName = b.Name, | |||
Describe = b.Describe, | |||
DeviceType = b.DeviceType, | |||
Id = a.Id, | |||
LineId = a.LineId | |||
}). | |||
ToListAsync(); | |||
return output; | |||
} | |||
/// <summary> | |||
@@ -162,7 +175,7 @@ | |||
var entity = await _dbContext.Queryable<Pztj_LineDevicesEntity>() | |||
.LeftJoin<Pztj_DevicesInfoEntity>((a,b)=>a.DeviceId==b.Id) | |||
.WhereIF(!string.IsNullOrEmpty(input.Name), (a, b) => b.Name.Contains(input.Name)) | |||
.Where((a, b) => a.LineId == input.LineId) | |||
.WhereIF(!string.IsNullOrEmpty(input.LineId), (a, b) => a.LineId == input.LineId) | |||
.Select((a,b)=>new ProductLineDeviceOutput | |||
{ | |||
DeviceId = a.DeviceId, | |||
@@ -207,12 +220,26 @@ | |||
/// 产线料仓不分页 | |||
/// </summary> | |||
/// <returns></returns> | |||
[HttpGet] | |||
public async Task<List<ProductLineStockOutput>> StockList() | |||
[HttpPost] | |||
public async Task<List<ProductLineStockOutput>> StockList(ProductLineStockQueryInput input) | |||
{ | |||
var entity = await _dbContext.Queryable<Pztj_LineStocksEntity>().ToListAsync(); | |||
List<ProductLineStockOutput> output = entity.Adapt<List<ProductLineStockOutput>>(); | |||
return output; | |||
var entity = await _dbContext.Queryable<Pztj_LineStocksEntity>() | |||
.LeftJoin<Pztj_StockInfoEntity>((a, b) => a.StockId == b.Id) | |||
.LeftJoin<Pztj_MaterialsInfoEntity>((a, b,c) => b.MaterialId == c.Id) | |||
.WhereIF(!string.IsNullOrEmpty(input.MaterialId), (a, b) => b.MaterialId == input.MaterialId) | |||
.WhereIF(!string.IsNullOrEmpty(input.LineId), (a, b) => a.LineId == input.LineId) | |||
.Select((a, b,c) => new ProductLineStockOutput | |||
{ | |||
Id = a.Id, | |||
LineId = a.LineId, | |||
StockCode = b.Code, | |||
StockId = b.Id, | |||
StockName = b.Name, | |||
MaterialId = b.MaterialId, | |||
MateriaName = c.Name | |||
}) | |||
.ToListAsync(); | |||
return entity; | |||
} | |||
/// <summary> | |||
/// 产线料仓分页 | |||
@@ -224,7 +251,7 @@ | |||
var entity = await _dbContext.Queryable<Pztj_LineStocksEntity>() | |||
.LeftJoin<Pztj_StockInfoEntity>((a, b) => a.StockId == b.Id) | |||
.WhereIF(!string.IsNullOrEmpty(input.Name), (a, b) => b.Name.Contains(input.Name)) | |||
.Where((a, b) => a.LineId == input.LineId) | |||
.WhereIF(!string.IsNullOrEmpty(input.LineId), (a, b) => a.LineId == input.LineId) | |||
.Select((a, b) => new ProductLineStockOutput | |||
{ | |||
StockId = a.StockId, | |||
@@ -0,0 +1,15 @@ | |||
namespace BPA.MES.Base.Application | |||
{ | |||
public interface ISysCacheService | |||
{ | |||
Task AddCacheKey(string cacheKey); | |||
Task DelCacheKey(string cacheKey); | |||
bool Exists(string cacheKey); | |||
Task<List<string>> GetAllCacheKeys(); | |||
Task<T> GetAsync<T>(string cacheKey); | |||
Task<string> GetStringAsync(string cacheKey); | |||
Task RemoveAsync(string key); | |||
Task SetAsync(string cacheKey, object value); | |||
Task SetStringAsync(string cacheKey, string value); | |||
} | |||
} |
@@ -0,0 +1,163 @@ | |||
using Furion.JsonSerialization; | |||
using Microsoft.Extensions.Caching.Distributed; | |||
using System.Text; | |||
namespace BPA.MES.Base.Application | |||
{ | |||
/// <summary> | |||
/// 系统缓存服务 | |||
/// </summary> | |||
[ApiDescriptionSettings(Name = "Cache", Order = 100)] | |||
public class SysCacheService : ISysCacheService, IDynamicApiController, ISingleton | |||
{ | |||
private readonly IDistributedCache _cache; | |||
public SysCacheService(IDistributedCache cache) | |||
{ | |||
_cache = cache; | |||
} | |||
/// <summary> | |||
/// 获取所有缓存关键字 | |||
/// </summary> | |||
/// <returns></returns> | |||
[HttpGet("sysCache/keyList")] | |||
public async Task<List<string>> GetAllCacheKeys() | |||
{ | |||
var res = await _cache.GetStringAsync(ClaimConst.CACHE_KEY_ALL); | |||
return string.IsNullOrWhiteSpace(res) ? null : JSON.Deserialize<List<string>>(res); | |||
} | |||
/// <summary> | |||
/// 删除指定关键字缓存 | |||
/// </summary> | |||
/// <param name="key"></param> | |||
/// <returns></returns> | |||
[HttpGet("sysCache/remove")] | |||
public async Task RemoveAsync(string key) | |||
{ | |||
await _cache.RemoveAsync(key); | |||
await DelCacheKey(key); | |||
} | |||
/// <summary> | |||
/// 删除某特征关键字缓存 | |||
/// </summary> | |||
/// <param name="key"></param> | |||
/// <returns></returns> | |||
[NonAction] | |||
public async Task DelByPatternAsync(string key) | |||
{ | |||
var allkeys = await GetAllCacheKeys(); | |||
var delAllkeys = allkeys.Where(u => u.Contains(key)).ToList(); | |||
// 删除相应的缓存 | |||
delAllkeys.ForEach(u => | |||
{ | |||
_cache.Remove(u); | |||
}); | |||
// 更新所有缓存键 | |||
allkeys = allkeys.Where(u => !u.Contains(key)).ToList(); | |||
await _cache.SetStringAsync(ClaimConst.CACHE_KEY_ALL, JSON.Serialize(allkeys)); | |||
} | |||
/// <summary> | |||
/// 设置缓存 | |||
/// </summary> | |||
/// <param name="cacheKey"></param> | |||
/// <param name="value"></param> | |||
/// <returns></returns> | |||
[NonAction] | |||
public async Task SetAsync(string cacheKey, object value) | |||
{ | |||
await _cache.SetAsync(cacheKey, Encoding.UTF8.GetBytes(JSON.Serialize(value))); | |||
await AddCacheKey(cacheKey); | |||
} | |||
/// <summary> | |||
/// 设置缓存 | |||
/// </summary> | |||
/// <param name="cacheKey"></param> | |||
/// <param name="value"></param> | |||
/// <returns></returns> | |||
[NonAction] | |||
public async Task SetStringAsync(string cacheKey, string value) | |||
{ | |||
await _cache.SetStringAsync(cacheKey, value); | |||
await AddCacheKey(cacheKey); | |||
} | |||
/// <summary> | |||
/// 获取缓存 | |||
/// </summary> | |||
/// <param name="cacheKey"></param> | |||
/// <returns></returns> | |||
[HttpGet("sysCache/detail")] | |||
public async Task<string> GetStringAsync(string cacheKey) | |||
{ | |||
return await _cache.GetStringAsync(cacheKey); | |||
} | |||
/// <summary> | |||
/// 获取缓存 | |||
/// </summary> | |||
/// <typeparam name="T"></typeparam> | |||
/// <param name="cacheKey"></param> | |||
/// <returns></returns> | |||
[NonAction] | |||
public async Task<T> GetAsync<T>(string cacheKey) | |||
{ | |||
var res = await _cache.GetAsync(cacheKey); | |||
return res == null ? default : JSON.Deserialize<T>(Encoding.UTF8.GetString(res)); | |||
} | |||
/// <summary> | |||
/// 检查给定 key 是否存在 | |||
/// </summary> | |||
/// <param name="cacheKey">键</param> | |||
/// <returns></returns> | |||
[NonAction] | |||
public bool Exists(string cacheKey) | |||
{ | |||
return _cache.Equals(cacheKey); | |||
} | |||
/// <summary> | |||
/// 增加缓存Key | |||
/// </summary> | |||
/// <param name="cacheKey"></param> | |||
/// <returns></returns> | |||
[NonAction] | |||
public async Task AddCacheKey(string cacheKey) | |||
{ | |||
var res = await _cache.GetStringAsync(ClaimConst.CACHE_KEY_ALL); | |||
var allkeys = string.IsNullOrWhiteSpace(res) ? new List<string>() : JSON.Deserialize<List<string>>(res); | |||
if (!allkeys.Any(m => m == cacheKey)) | |||
{ | |||
allkeys.Add(cacheKey); | |||
await _cache.SetStringAsync(ClaimConst.CACHE_KEY_ALL, JSON.Serialize(allkeys)); | |||
} | |||
} | |||
/// <summary> | |||
/// | |||
/// </summary> | |||
/// <param name="cacheKey"></param> | |||
/// <returns></returns> | |||
[NonAction] | |||
public async Task DelCacheKey(string cacheKey) | |||
{ | |||
var res = await _cache.GetStringAsync(ClaimConst.CACHE_KEY_ALL); | |||
var allkeys = string.IsNullOrWhiteSpace(res) ? new List<string>() : JSON.Deserialize<List<string>>(res); | |||
if (allkeys.Any(m => m == cacheKey)) | |||
{ | |||
allkeys.Remove(cacheKey); | |||
await _cache.SetStringAsync(ClaimConst.CACHE_KEY_ALL, JSON.Serialize(allkeys)); | |||
} | |||
} | |||
} | |||
} |
@@ -25,6 +25,10 @@ | |||
/// </summary> | |||
public string Number { get; set; } | |||
/// <summary> | |||
/// 设备id | |||
/// </summary> | |||
public string DeviceId { get; set; } | |||
/// <summary> | |||
/// 创建时间 | |||
/// </summary> | |||
public string CreateTime { get; set; } | |||
@@ -137,6 +141,14 @@ | |||
/// </summary> | |||
public string LineName { get; set; } | |||
/// <summary> | |||
/// 设备编码 | |||
/// </summary> | |||
public string DeviceCode { get; set; } | |||
/// <summary> | |||
/// 设备名称 | |||
/// </summary> | |||
public string DeviceName { get; set; } | |||
/// <summary> | |||
/// 工单状态 | |||
/// </summary> | |||
public WorkOrderStatusEnum? Status { get; set; } | |||
@@ -170,6 +182,9 @@ | |||
/// <summary> | |||
/// 物料信息 | |||
/// </summary> | |||
public List<WorkInfoMaterialsRecordEntity> MaterialList { get; set; } | |||
public List<WorkInfoMaterialsRecordOutput> MaterialList { get; set; } | |||
} | |||
} |
@@ -8,6 +8,42 @@ | |||
/// </summary> | |||
public class WorkInfoMaterialsRecordDto | |||
{ | |||
/// <summary> | |||
/// 物料名称 | |||
/// </summary> | |||
public string MaterialName { get; set; } | |||
/// <summary> | |||
/// 物料id | |||
/// </summary> | |||
public string MaterialId { get; set; } | |||
/// <summary> | |||
/// 工单id | |||
/// </summary> | |||
public string WorkId { get; set; } | |||
/// <summary> | |||
/// 重量 | |||
/// </summary> | |||
public string Weight { get; set; } | |||
/// <summary> | |||
/// 第几锅 | |||
/// </summary> | |||
public string PotNum { get; set; } | |||
/// <summary> | |||
/// 配方Id | |||
/// </summary> | |||
public string RecipeId { get; set; } | |||
/// <summary> | |||
/// 配方名称 | |||
/// </summary> | |||
public string RecipeName { get; set; } | |||
/// <summary> | |||
/// 物料状态 | |||
/// </summary> | |||
public EBatchingStatus MaterialStatus { get; set; } | |||
/// <summary> | |||
/// 更新时间 | |||
/// </summary> | |||
public DateTime? UpdateTime { get; set; } | |||
} | |||
/// <summary> | |||
/// 增加 | |||
@@ -56,5 +92,17 @@ | |||
/// 主键 | |||
/// </summary> | |||
public string Id { get; set; } | |||
/// <summary> | |||
/// 物料类型 | |||
/// </summary> | |||
public string MaterialType { get; set; } | |||
/// <summary> | |||
/// 物料类型名称 | |||
/// </summary> | |||
public string MaterialTypeName { get; set; } | |||
/// <summary> | |||
/// 每升重量 | |||
/// </summary> | |||
public string WeightPerLiter { get; set; } | |||
} | |||
} |
@@ -15,11 +15,16 @@ | |||
/// <summary> | |||
/// 工单状态 | |||
/// </summary> | |||
public string Status { get; set; } | |||
public WorkOrderStatusEnum Status { get; set; } | |||
/// <summary> | |||
/// 创建时间 | |||
/// </summary> | |||
public DateTime CreateTime { get; set; } | |||
/// <summary> | |||
/// 备注 | |||
/// </summary> | |||
public string Remark { get; set; } | |||
} | |||
/// <summary> | |||
/// 增加 | |||
@@ -41,6 +46,11 @@ | |||
/// 状态 | |||
/// </summary> | |||
public WorkOrderStatusEnum Status { get; set; } | |||
/// <summary> | |||
/// 备注 | |||
/// </summary> | |||
public string Remark { get; set; } | |||
} | |||
/// <summary> | |||
/// 删除 | |||
@@ -58,6 +68,20 @@ | |||
public class WorkInfoStatusQueryPageInput : RequestPage | |||
{ | |||
} | |||
/// <summary> | |||
/// 下发 | |||
/// </summary> | |||
public class PublishInput | |||
{ | |||
/// <summary> | |||
/// 工单ID | |||
/// </summary> | |||
public string WorkId { get; set; } | |||
/// <summary> | |||
/// 设备ID | |||
/// </summary> | |||
public string? DeviceId { get; set; } | |||
} | |||
/// <summary> | |||
/// 输出 | |||
@@ -68,5 +92,30 @@ | |||
/// 主键 | |||
/// </summary> | |||
public string Id { get; set; } | |||
/// <summary> | |||
/// 状态名称 | |||
/// </summary> | |||
public string StatusName { get { | |||
switch (Status) | |||
{ | |||
case WorkOrderStatusEnum.Unkown: | |||
return "未知"; | |||
case WorkOrderStatusEnum.Draft: | |||
return "草稿"; | |||
case WorkOrderStatusEnum.Issued: | |||
return "已下发"; | |||
case WorkOrderStatusEnum.Receive: | |||
return "已接受"; | |||
case WorkOrderStatusEnum.Started: | |||
return "已启动"; | |||
case WorkOrderStatusEnum.Completed: | |||
return "已完成"; | |||
case WorkOrderStatusEnum.Obsolete: | |||
return "废弃"; | |||
default: | |||
return "错误"; | |||
} | |||
} } | |||
} | |||
} |
@@ -53,9 +53,9 @@ | |||
/// <summary> | |||
/// 工单下发 | |||
/// </summary> | |||
/// <param name="workId">工单Id</param> | |||
/// <param name="input">工单Id</param> | |||
/// <returns></returns> | |||
Task<bool> Publish(string workId); | |||
Task<bool> Publish(PublishInput input); | |||
/// <summary> | |||
/// 强制结束 | |||
/// </summary> | |||
@@ -74,34 +74,51 @@ namespace BPA.MES.Base.Application.Services.WorkInfoService.Services | |||
.LeftJoin<Pztj_FinalsInfoEntity>((a, b) => a.FinalId == b.Id) | |||
.LeftJoin<ProductLineEntity>((a, b, c) => a.LineId == c.Id) | |||
.LeftJoin<Pztj_WorkInfoStatusEntity>((a, b, c, d) => d.Id == SqlFunc.Subqueryable<Pztj_WorkInfoStatusEntity>().Where(s => s.WorkId == a.Id).OrderByDesc(s => s.CreateTime).Select(s => s.Id)) | |||
.LeftJoin<Pztj_DevicesInfoEntity>((a,b,c,d,e)=>a.DeviceId==e.Id) | |||
.Where((a, b, c, d) => a.Id == Id) | |||
.Select((a, b, c, d) => new WorkInfoDetailOutput | |||
.Select((a, b, c, d, e) => new WorkInfoDetailOutput | |||
{ | |||
Id = a.Id.SelectAll(), | |||
DeviceCode = e.Code, | |||
DeviceName=e.Name, | |||
DeviceId = e.Id, | |||
FinalName = b.Name, | |||
LineName = c.Name, | |||
Status = d.Status == null ? WorkOrderStatusEnum.Draft : d.Status | |||
}).FirstAsync(); | |||
if (entity==null) | |||
if (entity == null) | |||
{ | |||
throw Oops.Bah("没有找到工单信息!"); | |||
} | |||
//获取成品信息 | |||
var finainfo = await _dbContext.Queryable<Pztj_FinalsInfoEntity>().FirstAsync(x => x.Id == entity.FinalId); | |||
if (finainfo==null) | |||
if (finainfo == null) | |||
{ | |||
throw Oops.Bah("没有找到成品信息!"); | |||
} | |||
//获取工艺步骤 | |||
var craftlist = await _dbContext.Queryable<WorkInfoCraftstepRecordEntity>().Where(x => x.WorkId == Id).ToListAsync(); | |||
//获取物料信息 | |||
var materiallist = await _dbContext.Queryable<WorkInfoMaterialsRecordEntity>().Where(x => x.WorkId == Id).ToListAsync(); | |||
var materiallist = await _dbContext.Queryable<WorkInfoMaterialsRecordEntity>() | |||
.LeftJoin<Pztj_MaterialsInfoEntity>((a,b)=>a.MaterialId==b.Id) | |||
.LeftJoin<DictDataEntity>((a,b,c) => b.Type == c.Id) | |||
.Where((a, b) => a.WorkId == Id) | |||
.Select((a, b,c) => | |||
new WorkInfoMaterialsRecordOutput | |||
{ | |||
Id = a.Id.SelectAll(), | |||
MaterialType = c.Id, | |||
MaterialTypeName = c.Value, | |||
WeightPerLiter = b.WeightPerLiter | |||
}) | |||
.ToListAsync(); | |||
entity.CraftList = craftlist; | |||
entity.MaterialList = materiallist; | |||
if(craftlist.Max(x=>x.Status) == RecipeStatus.执行完成 && craftlist.Max(x => x.Status) == craftlist.Min(x => x.Status)) | |||
if (craftlist.Max(x => x.Status) == RecipeStatus.执行完成 && craftlist.Max(x => x.Status) == craftlist.Min(x => x.Status)) | |||
{ | |||
entity.CraftStatus = RecipeStatus.执行完成; | |||
}else | |||
} | |||
else | |||
if (craftlist.Max(x => x.Status) == RecipeStatus.等待执行 && craftlist.Max(x => x.Status) == craftlist.Min(x => x.Status)) | |||
{ | |||
entity.CraftStatus = RecipeStatus.等待执行; | |||
@@ -141,8 +158,8 @@ namespace BPA.MES.Base.Application.Services.WorkInfoService.Services | |||
.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)) | |||
.WhereIF(input.StartTime != null, (a, b, c, d) => input.StartTime <= a.CreateTime) | |||
.WhereIF(input.EndTime != null, (a, b, c, d) => input.EndTime.Value.AddHours(23).AddMinutes(59).AddSeconds(59) >= a.CreateTime) | |||
.Select((a, b, c, d) => new WorkInfoOutput | |||
{ | |||
Id = a.Id.SelectAll(), | |||
@@ -169,6 +186,7 @@ namespace BPA.MES.Base.Application.Services.WorkInfoService.Services | |||
.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)) | |||
.OrderByDescending((a, b, c, d) => a.CreateTime) | |||
.Select((a, b, c, d) => new WorkInfoOutput | |||
{ | |||
Id = a.Id.SelectAll(), | |||
@@ -182,56 +200,71 @@ namespace BPA.MES.Base.Application.Services.WorkInfoService.Services | |||
/// <summary> | |||
/// 工单下发 | |||
/// </summary> | |||
/// <param name="workId">工单id</param> | |||
/// <param name="input">工单id</param> | |||
/// <returns></returns> | |||
/// <exception cref="NotImplementedException"></exception> | |||
[HttpPost] | |||
public async Task<bool> Publish(string workId) | |||
public async Task<bool> Publish(PublishInput input) | |||
{ | |||
string userId = App.User?.FindFirst(ClaimConst.CLAINM_USERID)?.Value; | |||
string userName = App.User?.FindFirst(ClaimConst.CLAINM_NAME)?.Value; | |||
if (!string.IsNullOrEmpty(input.DeviceId)) | |||
{ | |||
await _dbContext.Updateable<Pztj_WorkInfoEntity>().SetColumns(x => x.DeviceId == input.DeviceId).Where(x => x.Id == input.WorkId).ExecuteCommandAsync(); | |||
} | |||
var res = await UpdateStatus( | |||
new WorkInfoStatusUpdateInput | |||
{ | |||
WorkId = workId, | |||
Status = WorkOrderStatusEnum.Issued | |||
WorkId = input.WorkId, | |||
Status = WorkOrderStatusEnum.Issued, | |||
Remark = $"[{userId}]{userName}" | |||
}); | |||
var entity = await _dbContext.Queryable<Pztj_WorkInfoEntity>().FirstAsync(x => x.Id == workId); | |||
WorkInfoOutput workInfo = entity.Adapt<WorkInfoOutput>(); | |||
var workentity = await _dbContext.Queryable<Pztj_WorkInfoEntity>() | |||
.LeftJoin<Pztj_DevicesInfoEntity>((a,b)=>a.DeviceId==b.Id) | |||
.Where((a, b) => a.Id == input.WorkId) | |||
.Select((a,b)=>new WorkInfoOutput | |||
{ | |||
Id=a.Id.SelectAll(), | |||
DeviceCode = b.Code, | |||
DeviceName = b.Name | |||
}) | |||
.FirstAsync(); | |||
if (res) | |||
{ | |||
WorkInfoMaterialsRecordEntity workInfoMaterialsRecordEntity = new() | |||
WorkInfoMaterialsRecordEntity workInfoMaterialsRecordEntity = new() | |||
{ | |||
MaterialId = workId, | |||
MaterialId = input.WorkId, | |||
}; | |||
//获取成品信息 | |||
var finainfo = await _dbContext.Queryable<Pztj_FinalsInfoEntity>().FirstAsync(x => x.Id == entity.FinalId); | |||
var finainfo = await _dbContext.Queryable<Pztj_FinalsInfoEntity>().FirstAsync(x => x.Id == workentity.FinalId); | |||
if (finainfo == null) | |||
{ | |||
throw Oops.Bah("没有找到成品信息!"); | |||
} | |||
var materiallist = await _dbContext.Queryable<RecipeMaterialEntity>() | |||
.LeftJoin<Pztj_MaterialsInfoEntity>((a,b)=>a.MaterialId==b.Id) | |||
.Where((a, b) => a.RecipesId == finainfo.RecipeId) | |||
.Select((a, b) => new WorkInfoMaterialsRecordEntity | |||
.LeftJoin<Pztj_MaterialsInfoEntity>((a, b) => a.MaterialId == b.Id) | |||
.LeftJoin<RecipesInfoEntity>((a,b,c)=>a.RecipesId==c.Id) | |||
.Where((a, b, c) => a.RecipesId == finainfo.RecipeId) | |||
.Select((a, b, c) => new WorkInfoMaterialsRecordEntity | |||
{ | |||
MaterialId = a.MaterialId, | |||
MaterialName = b.Name, | |||
MaterialStatus = EBatchingStatus.等待配料, | |||
WorkId = workId, | |||
WorkId = input.WorkId, | |||
Weight = a.Weight, | |||
RecipeId = a.RecipesId, | |||
RecipeName = b.Name | |||
RecipeName = c.Name | |||
}) | |||
.ToListAsync(); | |||
//获取物料信息 | |||
var craftsteplist = await _dbContext.Queryable<Pztj_CraftStepsEntity>() | |||
.LeftJoin<Pztj_CraftsInfoEntity>((a,b)=>a.CraftId==b.Id) | |||
.LeftJoin<DeviceProductFunctionEntity>((a,b,c)=>a.DeviceProductFunctionId==c.Id) | |||
.Where((a,b)=>a.CraftId== finainfo.CraftId) | |||
.Select((a,b,c)=>new WorkInfoCraftstepRecordEntity | |||
.LeftJoin<Pztj_CraftsInfoEntity>((a, b) => a.CraftId == b.Id) | |||
.LeftJoin<DeviceProductFunctionEntity>((a, b, c) => a.DeviceProductFunctionId == c.Id) | |||
.Where((a, b) => a.CraftId == finainfo.CraftId) | |||
.Select((a, b, c) => new WorkInfoCraftstepRecordEntity | |||
{ | |||
CraftId = a.CraftId, | |||
CraftName = b.Name, | |||
@@ -241,12 +274,12 @@ namespace BPA.MES.Base.Application.Services.WorkInfoService.Services | |||
CraftstepParms = a.Params, | |||
Status = RecipeStatus.等待执行, | |||
Step = a.Step, | |||
WorkId = workId | |||
WorkId = input.WorkId | |||
}) | |||
.ToListAsync(); | |||
List<WorkInfoMaterialsRecordEntity> newmateriallist = new(); | |||
List<WorkInfoCraftstepRecordEntity> newcraftslist = new(); | |||
for (int i = 1; i <= Convert.ToInt32(entity.Number); i++) | |||
for (int i = 1; i <= Convert.ToInt32(workentity.Number); i++) | |||
{ | |||
foreach (var item in materiallist) | |||
{ | |||
@@ -276,7 +309,7 @@ namespace BPA.MES.Base.Application.Services.WorkInfoService.Services | |||
Status = item.Status, | |||
Step = item.Step, | |||
WorkId = item.WorkId, | |||
PotNum=i.ToString(), | |||
PotNum = i.ToString(), | |||
}; | |||
newcraftslist.Add(itementity); | |||
} | |||
@@ -284,8 +317,9 @@ namespace BPA.MES.Base.Application.Services.WorkInfoService.Services | |||
try | |||
{ | |||
_dbContext.Ado.BeginTran(); | |||
await _dbContext.Deleteable<WorkInfoCraftstepRecordEntity>().Where(x => x.WorkId == workId).ExecuteCommandAsync(); | |||
await _dbContext.Deleteable<WorkInfoMaterialsRecordEntity>().Where(x => x.WorkId == workId).ExecuteCommandAsync(); | |||
await _dbContext.Deleteable<WorkInfoCraftstepRecordEntity>().Where(x => x.WorkId == input.WorkId).ExecuteCommandAsync(); | |||
await _dbContext.Deleteable<WorkInfoMaterialsRecordEntity>().Where(x => x.WorkId == input.WorkId).ExecuteCommandAsync(); | |||
await _dbContext.Insertable(newcraftslist).ExecuteCommandAsync(); | |||
await _dbContext.Insertable(newmateriallist).ExecuteCommandAsync(); | |||
_dbContext.Ado.CommitTran(); | |||
@@ -295,7 +329,7 @@ namespace BPA.MES.Base.Application.Services.WorkInfoService.Services | |||
_dbContext.Ado.RollbackTran(); | |||
throw Oops.Oh("下发失败!"); | |||
} | |||
await _MQTTService.MqttPublish(workInfo, Topics.WorkOrderPush, MessageID.WorkOrderIssued); | |||
await _MQTTService.MqttPublish(new MqttPublishDto() { Payload = workentity, Topic = Topics.WorkOrderPush, MessageId = MessageID.WorkOrderIssued }); | |||
} | |||
return true; | |||
} | |||
@@ -367,12 +401,16 @@ namespace BPA.MES.Base.Application.Services.WorkInfoService.Services | |||
{ | |||
var entityFrist = await _dbContext.Queryable<WorkInfoCraftstepRecordEntity>().Where(x => x.Id == input.WorkCraftstepId).FirstAsync(); | |||
var entityFrist = await _dbContext.Queryable<WorkInfoCraftstepRecordEntity>().Where(x => x.Id == input.WorkCraftstepId).FirstAsync(); | |||
if (entityFrist==null) | |||
{ | |||
throw Oops.Bah("未查询到工单信息!"); | |||
} | |||
if (!string.IsNullOrEmpty(input.WorkId)) | |||
{ | |||
bool res = await _dbContext.Updateable<WorkInfoCraftstepRecordEntity>() | |||
.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(); | |||
.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 | |||
@@ -397,10 +435,13 @@ namespace BPA.MES.Base.Application.Services.WorkInfoService.Services | |||
[HttpPost] | |||
public async Task<bool> ForcedEnd(string workId) | |||
{ | |||
string userId = App.User?.FindFirst(ClaimConst.CLAINM_USERID)?.Value; | |||
string userName = App.User?.FindFirst(ClaimConst.CLAINM_NAME)?.Value; | |||
Pztj_WorkInfoStatusEntity entity = new() | |||
{ | |||
WorkId = workId, | |||
Status = WorkOrderStatusEnum.Completed | |||
Status = WorkOrderStatusEnum.Completed, | |||
Remark = $"{userName}[{userId}]点击你强制结束" | |||
}; | |||
var res = await _dbContext.Insertable(entity).IgnoreColumns(true).ExecuteCommandIdentityIntoEntityAsync(); | |||
return res; | |||
@@ -413,8 +454,9 @@ namespace BPA.MES.Base.Application.Services.WorkInfoService.Services | |||
[HttpGet] | |||
public async Task<List<WorkInfoStatusOutput>> StatusList(string workId) | |||
{ | |||
var entitys = await _dbContext.Queryable<Pztj_WorkInfoStatusEntity>().Where(x => x.WorkId == workId).ToListAsync(); | |||
var entitys = await _dbContext.Queryable<Pztj_WorkInfoStatusEntity>().Where(x => x.WorkId == workId).OrderByDescending(x=>x.CreateTime).ToListAsync(); | |||
List<WorkInfoStatusOutput> list = entitys.Adapt<List<WorkInfoStatusOutput>>(); | |||
return list; | |||
} | |||
} | |||
@@ -39,6 +39,10 @@ namespace BPA.MES.Base.Core | |||
{ | |||
entityInfo.SetValue(DateTime.Now); | |||
}; | |||
if (entityInfo.PropertyName == "CreateDate" && entityInfo.OperationType == DataFilterType.InsertByObject) | |||
{ | |||
entityInfo.SetValue(DateTime.Now); | |||
}; | |||
}; | |||
} | |||
); | |||
@@ -56,35 +56,6 @@ public class Startup : AppStartup | |||
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<IMqttClientOptions>(); | |||
// //await builder.Build().Services.GetService<IMqttClient>().ConnectAsync(options); | |||
// } | |||
// catch (global::System.Exception) | |||
// { | |||
// } | |||
// }); | |||
// op.MqttApplicationMessageReceivedHandler = new MQTTnet.Client.Receiving.MqttApplicationMessageReceivedHandlerDelegate(async e => | |||
// { | |||
// }); | |||
//}); | |||
services.AddControllers() | |||
.AddInjectWithUnifyResult(); | |||
} | |||
@@ -0,0 +1,5 @@ | |||
{ | |||
"version": 1, | |||
"isRoot": true, | |||
"tools": {} | |||
} |
@@ -5,5 +5,6 @@ | |||
</PropertyGroup> | |||
<PropertyGroup> | |||
<ActiveDebugProfile>BPA.MES.Base.Web.Entry</ActiveDebugProfile> | |||
<NameOfLastUsedPublishProfile>D:\胖子天骄\PZTJ.MES\backend\BPA.MES.Base.Web.Entry\Properties\PublishProfiles\FolderProfile.pubxml</NameOfLastUsedPublishProfile> | |||
</PropertyGroup> | |||
</Project> |
@@ -0,0 +1,21 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<!-- | |||
https://go.microsoft.com/fwlink/?LinkID=208121. | |||
--> | |||
<Project> | |||
<PropertyGroup> | |||
<DeleteExistingFiles>true</DeleteExistingFiles> | |||
<ExcludeApp_Data>false</ExcludeApp_Data> | |||
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish> | |||
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration> | |||
<LastUsedPlatform>Any CPU</LastUsedPlatform> | |||
<PublishProvider>FileSystem</PublishProvider> | |||
<PublishUrl>bin\Release\net6.0\publish\</PublishUrl> | |||
<WebPublishMethod>FileSystem</WebPublishMethod> | |||
<SiteUrlToLaunchAfterPublish /> | |||
<TargetFramework>net6.0</TargetFramework> | |||
<RuntimeIdentifier>win-x64</RuntimeIdentifier> | |||
<ProjectGuid>c8d99f52-edc7-411f-8300-6db14bf59e8c</ProjectGuid> | |||
<SelfContained>true</SelfContained> | |||
</PropertyGroup> | |||
</Project> |
@@ -0,0 +1,10 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<!-- | |||
https://go.microsoft.com/fwlink/?LinkID=208121. | |||
--> | |||
<Project> | |||
<PropertyGroup> | |||
<_PublishTargetUrl>D:\胖子天骄\PZTJ.MES\backend\BPA.MES.Base.Web.Entry\bin\Release\net6.0\publish\</_PublishTargetUrl> | |||
<History>True|2023-11-03T01:49:49.8809253Z;True|2023-10-19T18:26:28.9736059+08:00;True|2023-10-19T12:20:00.3256982+08:00;True|2023-10-18T11:41:41.7977602+08:00;True|2023-10-17T18:56:25.1421613+08:00;True|2023-10-16T15:43:05.7944751+08:00;True|2023-10-15T17:28:41.6387899+08:00;True|2023-10-14T18:02:29.7904729+08:00;True|2023-10-14T10:58:09.1850768+08:00;False|2023-10-14T10:57:38.1803146+08:00;True|2023-10-10T15:43:25.4511019+08:00;False|2023-10-10T15:34:09.4564943+08:00;False|2023-10-09T14:10:16.8583415+08:00;True|2023-10-09T14:07:07.0884367+08:00;True|2023-10-09T13:50:15.6186644+08:00;True|2023-10-09T12:23:40.9180586+08:00;</History> | |||
</PropertyGroup> | |||
</Project> |
@@ -22,7 +22,7 @@ | |||
"environmentVariables": { | |||
"ASPNETCORE_ENVIRONMENT": "Development" | |||
}, | |||
"applicationUrl": "http://localhost:5002", | |||
"applicationUrl": "http://172.16.12.102:5002", | |||
"dotnetRunMessages": true | |||
}, | |||
"Docker": { | |||
@@ -10,9 +10,11 @@ | |||
"AllowedHosts": "*", | |||
"ConnectionConfigs": [ | |||
{ | |||
"ConnectionString": "server=10.2.1.254;Port=3306;Database=bpa_pztj_mes;Uid=root;Pwd=BapAdmin123456.;", | |||
//"ConnectionString": "server=10.2.1.254;Port=3306;Database=bpa_pztj_mes;Uid=root;Pwd=BapAdmin123456.;", | |||
"ConnectionString": "server=192.168.1.231;Port=3306;Database=bpa_pztj_mes;Uid=root;Pwd=pztj8127;", | |||
"DbType": "MySql", | |||
"IsAutoCloseConnection": true | |||
} | |||
] | |||
], | |||
"AGVUrl": "http://172.16.12.206:10080" | |||
} |