diff --git a/DOAN.Model/MES/recipe/Dto/PfRecipeIssueLogDto.cs b/DOAN.Model/MES/recipe/Dto/PfRecipeIssueLogDto.cs
index 1196a2d..e429f33 100644
--- a/DOAN.Model/MES/recipe/Dto/PfRecipeIssueLogDto.cs
+++ b/DOAN.Model/MES/recipe/Dto/PfRecipeIssueLogDto.cs
@@ -19,25 +19,70 @@ namespace DOAN.Model.MES.recipe.Dto
///
public class PfRecipeIssueLogDto
{
- public string Receiver { get; set; }
+ ///
+ /// 下达记录ID(主键)
+ ///
+ public int Id { get; set; }
+ ///
+ /// 配方码
+ ///
+ public string RecipeCode { get; set; }
+
+ ///
+ /// 版本编号
+ ///
+ public string Version { get; set; }
+
+ ///
+ /// 下达时间
+ ///
+
+ public DateTime? IssueTime { get; set; }
+
+
+ ///
+ /// 工单号
+ ///
+
+ public string Workorder { get; set; }
+
+ ///
+ /// 产品码
+ ///
+
+ public string ProductCode { get; set; }
+
+ ///
+ /// 产品名称
+ ///
+
+ public string ProductName { get; set; }
+
+
+ ///
+ /// 创建人
+ ///
+
public string CreatedBy { get; set; }
+ ///
+ /// 创建时间
+ ///
+
public DateTime? CreatedTime { get; set; }
+ ///
+ /// 更新人
+ ///
+
public string UpdatedBy { get; set; }
+ ///
+ /// 更新时间
+ ///
+
public DateTime? UpdatedTime { get; set; }
- public int Id { get; set; }
-
- public string RecipeCode { get; set; }
-
- public string Version { get; set; }
-
- public DateTime? IssueTime { get; set; }
-
- public string IssuedBy { get; set; }
-
}
}
\ No newline at end of file
diff --git a/DOAN.Model/MES/recipe/PfRecipeIssueLog.cs b/DOAN.Model/MES/recipe/PfRecipeIssueLog.cs
index 573491a..34f78dd 100644
--- a/DOAN.Model/MES/recipe/PfRecipeIssueLog.cs
+++ b/DOAN.Model/MES/recipe/PfRecipeIssueLog.cs
@@ -7,10 +7,50 @@ namespace DOAN.Model.MES.recipe
[SugarTable("pf_recipe_issue_log")]
public class PfRecipeIssueLog
{
+
+
///
- /// 接收方
+ /// 下达记录ID(主键)
///
- public string Receiver { get; set; }
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
+ public int Id { get; set; }
+
+ ///
+ /// 配方码
+ ///
+ [SugarColumn(ColumnName = "recipe_code")]
+ public string RecipeCode { get; set; }
+
+ ///
+ /// 版本编号
+ ///
+ public string Version { get; set; }
+
+ ///
+ /// 下达时间
+ ///
+ [SugarColumn(ColumnName = "issue_time")]
+ public DateTime? IssueTime { get; set; }
+
+
+ ///
+ /// 工单号
+ ///
+ [SugarColumn(ColumnName = "workorder")]
+ public string Workorder { get; set; }
+
+ ///
+ /// 产品码
+ ///
+ [SugarColumn(ColumnName = "productcode")]
+ public string ProductCode { get; set; }
+
+ ///
+ /// 产品名称
+ ///
+ [SugarColumn(ColumnName = "productname")]
+ public string ProductName { get; set; }
+
///
/// 创建人
@@ -36,34 +76,5 @@ namespace DOAN.Model.MES.recipe
[SugarColumn(ColumnName = "updated_time")]
public DateTime? UpdatedTime { get; set; }
- ///
- /// 下达记录ID(主键)
- ///
- [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
- public int Id { get; set; }
-
- ///
- /// 配方码
- ///
- [SugarColumn(ColumnName = "recipe_code")]
- public string RecipeCode { get; set; }
-
- ///
- /// 版本编号
- ///
- public string Version { get; set; }
-
- ///
- /// 下达时间
- ///
- [SugarColumn(ColumnName = "issue_time")]
- public DateTime? IssueTime { get; set; }
-
- ///
- /// 下达人
- ///
- [SugarColumn(ColumnName = "issued_by")]
- public string IssuedBy { get; set; }
-
}
}
\ No newline at end of file
diff --git a/DOAN.Service/Mobile/IService/IPADReportWorkService.cs b/DOAN.Service/Mobile/IService/IPADReportWorkService.cs
index 301c52b..9642d47 100644
--- a/DOAN.Service/Mobile/IService/IPADReportWorkService.cs
+++ b/DOAN.Service/Mobile/IService/IPADReportWorkService.cs
@@ -20,6 +20,6 @@ public interface IPADReportWorkService
int UpdateProReportwork(ProReportwork parm);
- int StartWorkOrder(string workorder);
+ Task StartWorkOrder(string workorder);
int FinishWorkOrder(string workorder);
}
\ No newline at end of file
diff --git a/DOAN.Service/Mobile/PADReportWorkService.cs b/DOAN.Service/Mobile/PADReportWorkService.cs
index 0c8daa2..50bc1f5 100644
--- a/DOAN.Service/Mobile/PADReportWorkService.cs
+++ b/DOAN.Service/Mobile/PADReportWorkService.cs
@@ -1,8 +1,10 @@
+using DOAN.Infrastructure.Helper;
using DOAN.Model;
using DOAN.Model.MES.base_;
using DOAN.Model.MES.mm;
using DOAN.Model.MES.product;
using DOAN.Model.MES.product.Dto;
+using DOAN.Model.MES.recipe;
using DOAN.Repository;
using DOAN.Service.MES.mm.line;
using DOAN.Service.Mobile.IService;
@@ -162,7 +164,7 @@ namespace DOAN.Service.Mobile
return Update(model, true);
}
- public int StartWorkOrder(string workorder)
+ public async Task StartWorkOrder(string workorder)
{
var result = 0;
// 获取同一天 同一组 同一线 的所有工单 把状态2 设为init 1
@@ -184,9 +186,53 @@ namespace DOAN.Service.Mobile
});
//TODO 拼接MQTT消息,发送给设备,工单信息和配方信息
- Context.Queryable
+ var RecipeMesg= Context.Queryable().LeftJoin((rpr, r) => rpr.RecipeCode == r.RecipeCode)
+ .Where((rpr, r) => rpr.Productcode == handleWorkorder.ProductionCode)
+ .Where((rpr, r) => r.Status == 1)
+ .Select((rpr, r) => new
+ {
+ RecipeCode = r.RecipeCode,
+ Version = r.Version,
+ ParamList = Context.Queryable().Where(it => it.RecipeCode == r.RecipeCode && it.Version == r.Version).ToList()
+ }).First();
+ if( RecipeMesg==null)
+ {
+ throw new Exception("未找到对应的配方信息,请检查产品与配方的关联关系,或配方状态是否有效");
+ }
+
+ // 合并两个对象为匿名对象
+ var combinedObject = new
+ {
+ WorkorderInfo = handleWorkorder,
+ RecipeInfo = RecipeMesg
+ };
+ string jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(combinedObject, Newtonsoft.Json.Formatting.Indented);
+ //插入配方派发日志
+ PfRecipeIssueLog pfRecipeIssueLog = new PfRecipeIssueLog();
+ pfRecipeIssueLog.RecipeCode = RecipeMesg.RecipeCode;
+ pfRecipeIssueLog.Version = RecipeMesg.Version;
+ pfRecipeIssueLog.IssueTime = DateTime.Now;
+ pfRecipeIssueLog.Workorder = handleWorkorder.Workorder;
+ pfRecipeIssueLog.ProductCode = handleWorkorder.ProductionCode;
+ pfRecipeIssueLog.ProductName = handleWorkorder.ProductionName;
+ pfRecipeIssueLog.CreatedBy = "PDA";
+ pfRecipeIssueLog.CreatedTime = DateTime.Now;
+ Context.Insertable(pfRecipeIssueLog).ExecuteCommand();
+
+
+ MqttHelper _mqttHelper=new MqttHelper("mqtt://192.168.50.163", 8883);
+
+ // 连接
+ await _mqttHelper.ConnectAsync();
+
+ // 发送多条消息
+
+ await _mqttHelper.PublishMessageAsync("MES/Workorder/Start", jsonString);
+
+ // 断开连接
+ await _mqttHelper.DisconnectAsync();
return result;
diff --git a/Infrastructure/DOAN.Infrastructure.csproj b/Infrastructure/DOAN.Infrastructure.csproj
index afa789c..a42dadc 100644
--- a/Infrastructure/DOAN.Infrastructure.csproj
+++ b/Infrastructure/DOAN.Infrastructure.csproj
@@ -18,6 +18,7 @@
+
diff --git a/Infrastructure/Helper/MqttHelper.cs b/Infrastructure/Helper/MqttHelper.cs
new file mode 100644
index 0000000..063634f
--- /dev/null
+++ b/Infrastructure/Helper/MqttHelper.cs
@@ -0,0 +1,169 @@
+using MQTTnet;
+using MQTTnet.Formatter;
+using MQTTnet.Protocol;
+using System;
+using System.Threading.Tasks;
+namespace DOAN.Infrastructure.Helper
+{
+
+ ///
+ /// MQTT 消息发送工具类
+ ///
+ public class MqttHelper : IDisposable
+ {
+ // MQTT Broker 配置(可外部设置或配置文件读取)
+ public string MqttBrokerUrl { get; set; } = "broker.hivemq.com";
+ public int MqttBrokerPort { get; set; } = 1883;
+ public string MqttUsername { get; set; } = null;
+ public string MqttPassword { get; set; } = null;
+
+ private IMqttClient _mqttClient;
+
+ private bool _disposed = false;
+
+ ///
+ /// 构造函数 - 使用默认配置
+ ///
+ public MqttHelper() { }
+
+ ///
+ /// 构造函数 - 自定义配置
+ ///
+ public MqttHelper(string brokerUrl, int brokerPort, string username = null, string password = null)
+ {
+ MqttBrokerUrl = brokerUrl;
+ MqttBrokerPort = brokerPort;
+ MqttUsername = username;
+ MqttPassword = password;
+ }
+
+ ///
+ /// 连接到 MQTT Broker
+ ///
+ public async Task ConnectAsync()
+ {
+ try
+ {
+ if (_mqttClient?.IsConnected == true)
+ {
+ Console.WriteLine("MQTT 客户端已经连接");
+ return true;
+ }
+
+ var factory = new MqttClientFactory();
+ _mqttClient = factory.CreateMqttClient();
+
+ var options = new MqttClientOptionsBuilder()
+ .WithTcpServer(MqttBrokerUrl, MqttBrokerPort)
+ .WithCredentials(MqttUsername, MqttPassword)
+ .WithCleanSession()
+ .Build();
+
+ Console.WriteLine($"正在连接到 MQTT Broker: {MqttBrokerUrl}:{MqttBrokerPort}...");
+ await _mqttClient.ConnectAsync(options);
+
+ Console.WriteLine("✅ MQTT 连接成功!");
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"❌ MQTT 连接失败: {ex.Message}");
+ return false;
+ }
+ }
+
+ ///
+ /// 发送消息到指定主题
+ ///
+ /// 目标主题
+ /// 消息内容
+ /// QoS 级别,默认为 AtLeastOnce(1)
+ /// 是否保留消息,默认为 false
+ public async Task PublishMessageAsync(string topic, string messageContent,
+ MqttQualityOfServiceLevel qosLevel = MqttQualityOfServiceLevel.AtLeastOnce,
+ bool retain = false)
+ {
+ try
+ {
+ if (_mqttClient?.IsConnected != true)
+ {
+ Console.WriteLine("MQTT 客户端未连接,尝试重新连接...");
+ if (!await ConnectAsync())
+ {
+ Console.WriteLine("❌ 重连失败,无法发送消息");
+ return false;
+ }
+ }
+
+ var message = new MqttApplicationMessageBuilder()
+ .WithTopic(topic)
+ .WithPayload(messageContent)
+ .WithQualityOfServiceLevel(qosLevel)
+ .WithRetainFlag(retain)
+ .Build();
+
+ Console.WriteLine($"正在向主题 '{topic}' 发送消息: {messageContent}");
+ await _mqttClient.PublishAsync(message);
+
+ Console.WriteLine("✅ 消息发送成功!");
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"❌ 消息发送失败: {ex.Message}");
+ return false;
+ }
+ }
+
+ ///
+ /// 发送消息(使用默认主题配置)
+ ///
+ /// 消息内容
+ /// QoS 级别
+ /// 是否保留消息
+ public async Task PublishMessageAsync(string messageContent,
+ MqttQualityOfServiceLevel qosLevel = MqttQualityOfServiceLevel.AtLeastOnce,
+ bool retain = false)
+ {
+ return await PublishMessageAsync("product/topic", messageContent, qosLevel, retain);
+ }
+
+ ///
+ /// 断开 MQTT 连接
+ ///
+ public async Task DisconnectAsync()
+ {
+ try
+ {
+ if (_mqttClient?.IsConnected == true)
+ {
+ await _mqttClient.DisconnectAsync();
+ Console.WriteLine("🔌 MQTT 已断开连接");
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"❌ 断开连接时发生错误: {ex.Message}");
+ }
+ }
+
+ ///
+ /// 检查是否已连接
+ ///
+ public bool IsConnected => _mqttClient?.IsConnected == true;
+
+ ///
+ /// 释放资源
+ ///
+ public void Dispose()
+ {
+ if (!_disposed)
+ {
+ DisconnectAsync().Wait();
+ _mqttClient?.Dispose();
+ _disposed = true;
+ }
+ }
+ }
+
+}