using CMS.Extensions.Variable; using CMS.Plugin.FlowManagement.Abstractions.FlowBusiness; using CMS.Plugin.PipeLineLems.Apis; using CMS.Plugin.PipeLineLems.Application.Contracts.Dtos.MyTestEntityNames; using CMS.Plugin.PipeLineLems.Domain.MyTestEntityNames; using CMS.Plugin.PipeLineLems.Jobs; using CMS.Plugin.ProcessManagement.Abstractions; using CMS.Plugin.TraceManagement.Abstractions.Models.Traces; using CMS.Plugin.TraceManagement.Abstractions; using CMS.Project; using CMS.Project.Abstractions; using CMS.Unit.RuntimeValue.Abstractions; using KissUtil.Extensions; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System; using Volo.Abp.BackgroundJobs; using Volo.Abp.Uow; using CMS.Plugin.PipeLineLems.Application.Contracts.Services; using CMS.Plugin.PipeLineLems.Domain.WorkPlan; using CMS.Plugin.PipeLineLems.Domain.CallMaterialOrder; using System.Collections.Generic; using CMS.Framework.AspNetCore.Users; using NPOI.SS.Formula.Functions; using CMS.Plugin.PipeLineLems.Application.Implements; using CmsQueryExtensions.Entitys; using CMS.Plugin.PipeLineLems.Domain.WorkTask; namespace CMS.Plugin.PipeLineLems.ProjectService { /// /// 工程服务,和工程关联的后台服务,当以当前Key调用时会被执行 /// public class PipeLineLemsProjectService : BaseProjectService { private IServiceProvider _serviceProvider; private readonly ILogger _logger; private readonly IVariableDataCache _variableDataCache; /// /// 变量服务 /// private readonly VariableService _variableService; private FlowVariableChannelListener _channelListener; private Dictionary _monitorVariableNames; /// /// 服务的Key,唯一,供使用 /// public override string Key => "PipeLineLems"; /// /// 服务描述,显示在服务列表UI上的名称 /// public override string Description => "PipeLineLems服务"; /// /// 启用授权 /// public override bool AuthRequired => true; /// /// Initializes a new instance of the class. /// /// The logger. /// The variable data cache. public PipeLineLemsProjectService( VariableService variableService, IServiceProvider serviceProvider, ILogger logger, IVariableDataCache variableDataCache) { _serviceProvider = serviceProvider; _logger = logger; _variableDataCache = variableDataCache; _variableService = variableService; } /// /// 开启服务 /// /// 具有工程上下文的实例 public override async Task StartAsync(IServiceProvider serviceProvider) { if (State == ProjectServiceState.Started) { return; } // 监听变量 _monitorVariableNames = new Dictionary { { "打码进站信号", "打码进站信号(描述)" }, { "请求生成打码产品码信号", "请求生成打码产品码信号(描述)" }, { "请求生成切割产品码信号", "请求生成切割产品码信号(描述)" }, { "切割进站信号", "切割进站信号(描述)" }, { "装配完工信号", "装配完工信号(描述)" }, { "焊接完工信号", "焊接完工信号(描述)" }, { "法兰冲码完工信号", "法兰冲码完工信号(描述)" }, }; // 创建通道监听 _channelListener?.Token?.Dispose(); _channelListener = new FlowVariableChannelListener(_logger, _variableDataCache); _channelListener.CreateChannel(Key, waitListener: false, timeout: TimeSpan.FromSeconds(30), variableFilter: _monitorVariableNames.Keys.ToHashSet()); _channelListener.TagChanged += OnTagValueChanged; await base.StartAsync(serviceProvider); } /// /// 停止服务 /// /// 具有工程上下文的实例 public override async Task StopAsync(IServiceProvider serviceProvider) { if (_channelListener != null) { // 释放监听 _channelListener.TagChanged -= OnTagValueChanged; _channelListener.Token.Dispose(); _channelListener = null; } // 使用后台作业异步处理 //await _serviceProvider.GetRequiredService().EnqueueAsync(new PipeLineLemsArgs //{ // Subject = "PipeLineLems_Subject", // Body = "PipeLineLems_Body", //}); await base.StopAsync(serviceProvider); } /// /// Called when [tag value changed]. /// /// The sender. /// The instance containing the event data. private async void OnTagValueChanged(object sender, TagChangedEventArgs e) { var changeds = e.Changeds.Where(x => _monitorVariableNames != null && _monitorVariableNames.ContainsKey(x.Name)); if (!changeds.Any()) { return; } foreach (var changed in changeds) { var oldValue = changed.Old?.Value; var newValue = changed.New?.Value; var traceId = e.TraceId; _logger.LogInformation($"{changed.Name} 变量值发生变化,旧值{oldValue}=新值{newValue},TraceId={traceId}"); if (changed.Name == "请求生成打码产品码信号") { // TODO: 处理变量值变化 // Tips:https://cms-docs.shengyc.com/cms/api/%E5%90%8E%E7%AB%AF#3-%E5%8F%98%E9%87%8F%E6%A8%A1%E5%9D%97 /* 说明:通过订阅 IVariableDataCache.TagChanged 事件,您可以实时监控变量的变化。此事件会传递所有变量至事件处理函数,因此,业务层需在函数中筛选关注的变量。 注意事项: (1)性能影响: 发布事件时,事件的发送者将阻塞流程。因此,强烈建议避免在事件处理函数中执行 I/ O 操作、HTTP 接口访问或其他耗时操作,以防止对系统性能产生严重影响,导致整个系统响应延迟。 (2)高频率触发: 由于事件订阅了全量变量,触发频率可能非常高。 (3)异步处理: 鉴于事件触发频率很高,建议业务层在筛选关注变量后,使用 Task 启动新线程处理业务逻辑,以避免阻塞核心的变量监听功能,实现业务层与平台基座的解耦。 (4)并发管理: 如果业务层并发量大,必须优化代码设计和实施,以减少在高并发情况下的系统资源消耗,防止系统性能问题。 (5)代码安全: 安装并使用 CMS.CodeAnalysis 分析器来分析 IVariableDataCache.TagChanged 的使用情况。该工具能在使用不当时提供编译错误,帮助您提高代码质量。*/ if (changed.New?.Value.SafeString().ToBool() == true) { _ = Task.Run(async () => { await HanlderForPringBarCodeByCreateProductAsync(); }); } else { _ = Task.Run(async () => { await HanlderForPringBarCodeByCreateProductWhenFalseAsync(); }); } } if (changed.Name == "打码进站信号" && changed.New?.Value.SafeString().ToBool() == true) { // TODO: 处理变量值变化 // Tips:https://cms-docs.shengyc.com/cms/api/%E5%90%8E%E7%AB%AF#3-%E5%8F%98%E9%87%8F%E6%A8%A1%E5%9D%97 /* 说明:通过订阅 IVariableDataCache.TagChanged 事件,您可以实时监控变量的变化。此事件会传递所有变量至事件处理函数,因此,业务层需在函数中筛选关注的变量。 注意事项: (1)性能影响: 发布事件时,事件的发送者将阻塞流程。因此,强烈建议避免在事件处理函数中执行 I/ O 操作、HTTP 接口访问或其他耗时操作,以防止对系统性能产生严重影响,导致整个系统响应延迟。 (2)高频率触发: 由于事件订阅了全量变量,触发频率可能非常高。 (3)异步处理: 鉴于事件触发频率很高,建议业务层在筛选关注变量后,使用 Task 启动新线程处理业务逻辑,以避免阻塞核心的变量监听功能,实现业务层与平台基座的解耦。 (4)并发管理: 如果业务层并发量大,必须优化代码设计和实施,以减少在高并发情况下的系统资源消耗,防止系统性能问题。 (5)代码安全: 安装并使用 CMS.CodeAnalysis 分析器来分析 IVariableDataCache.TagChanged 的使用情况。该工具能在使用不当时提供编译错误,帮助您提高代码质量。*/ _ = Task.Run(async () => { await HanlderForPringBarCodeAsync(); // 例1:同步处理 //await ProcessAsync(); // 例2:调用外部API //await ExecuteExternalApiAsync(); }); } if (changed.Name == "切割进站信号" && changed.New?.Value.SafeString().ToBool() == true) { // TODO: 处理变量值变化 // Tips:https://cms-docs.shengyc.com/cms/api/%E5%90%8E%E7%AB%AF#3-%E5%8F%98%E9%87%8F%E6%A8%A1%E5%9D%97 /* 说明:通过订阅 IVariableDataCache.TagChanged 事件,您可以实时监控变量的变化。此事件会传递所有变量至事件处理函数,因此,业务层需在函数中筛选关注的变量。 注意事项: (1)性能影响: 发布事件时,事件的发送者将阻塞流程。因此,强烈建议避免在事件处理函数中执行 I/ O 操作、HTTP 接口访问或其他耗时操作,以防止对系统性能产生严重影响,导致整个系统响应延迟。 (2)高频率触发: 由于事件订阅了全量变量,触发频率可能非常高。 (3)异步处理: 鉴于事件触发频率很高,建议业务层在筛选关注变量后,使用 Task 启动新线程处理业务逻辑,以避免阻塞核心的变量监听功能,实现业务层与平台基座的解耦。 (4)并发管理: 如果业务层并发量大,必须优化代码设计和实施,以减少在高并发情况下的系统资源消耗,防止系统性能问题。 (5)代码安全: 安装并使用 CMS.CodeAnalysis 分析器来分析 IVariableDataCache.TagChanged 的使用情况。该工具能在使用不当时提供编译错误,帮助您提高代码质量。*/ _ = Task.Run(async () => { await HanlderForCutAsync(); // 例1:同步处理 //await ProcessAsync(); // 例2:调用外部API //await ExecuteExternalApiAsync(); }); } if (changed.Name == "请求生成切割产品码信号") { // TODO: 处理变量值变化 // Tips:https://cms-docs.shengyc.com/cms/api/%E5%90%8E%E7%AB%AF#3-%E5%8F%98%E9%87%8F%E6%A8%A1%E5%9D%97 /* 说明:通过订阅 IVariableDataCache.TagChanged 事件,您可以实时监控变量的变化。此事件会传递所有变量至事件处理函数,因此,业务层需在函数中筛选关注的变量。 注意事项: (1)性能影响: 发布事件时,事件的发送者将阻塞流程。因此,强烈建议避免在事件处理函数中执行 I/ O 操作、HTTP 接口访问或其他耗时操作,以防止对系统性能产生严重影响,导致整个系统响应延迟。 (2)高频率触发: 由于事件订阅了全量变量,触发频率可能非常高。 (3)异步处理: 鉴于事件触发频率很高,建议业务层在筛选关注变量后,使用 Task 启动新线程处理业务逻辑,以避免阻塞核心的变量监听功能,实现业务层与平台基座的解耦。 (4)并发管理: 如果业务层并发量大,必须优化代码设计和实施,以减少在高并发情况下的系统资源消耗,防止系统性能问题。 (5)代码安全: 安装并使用 CMS.CodeAnalysis 分析器来分析 IVariableDataCache.TagChanged 的使用情况。该工具能在使用不当时提供编译错误,帮助您提高代码质量。*/ if (changed.New?.Value.SafeString().ToBool() == true) { _ = Task.Run(async () => { await HanlderForCutByCreateProductAsync(); }); } else { _ = Task.Run(async () => { await HanlderForCutByCreateProductWhenFlaseAsync(); }); } } if (changed.Name == "装配完工信号") { if (changed.New?.Value.SafeString().ToBool() == true) { _ = Task.Run(async () => { await HanlderFor装配完工信号Async(); }); } else { _ = Task.Run(async () => { await HanlderFor完工信号WhenFalseAsync("装配"); }); } } if (changed.Name == "焊接完工信号") { if (changed.New?.Value.SafeString().ToBool() == true) { _ = Task.Run(async () => { await HanlderFor焊接完工信号Async(); }); } else { _ = Task.Run(async () => { await HanlderFor完工信号WhenFalseAsync("焊接"); }); } } if (changed.Name == "法兰冲码完工信号") { if (changed.New?.Value.SafeString().ToBool() == true) { _ = Task.Run(async () => { await HanlderFor法兰冲码完工信号Async(); }); } else { _ = Task.Run(async () => { await HanlderFor完工信号WhenFalseAsync("法兰冲码"); }); } } } } /// /// Processes the asynchronous. /// private async Task ProcessAsync() { using var scope = _serviceProvider.CreateScope(); var unitOfWorkManager = scope.ServiceProvider.GetRequiredService(); using var uow = unitOfWorkManager.Begin(requiresNew: true); var mytestentitynameRepository = scope.ServiceProvider.GetRequiredService(); var count = await mytestentitynameRepository.GetCountAsync(); // 如果有更新数据库操作,需提交保存 // await uow.SaveChangesAsync(); _logger.LogInformation($"ProcessAsync,Count={count}"); } /// /// Executes the external API. /// private async Task ExecuteExternalApiAsync() { try { await _serviceProvider.GetRequiredService().CreateAsync(new MyTestEntityNameCreateDto { Name = "MyTestEntityName_Name", Code = "MyTestEntityName_Code", }); } catch (Exception e) { _logger.LogException(e); } } /// /// 打码进站信号 /// /// private async Task HanlderForPringBarCodeAsync() { var workPlanAppService = _serviceProvider.GetRequiredService(); var workPlanRepository = _serviceProvider.GetRequiredService(); var callMaterialOrderAppService = _serviceProvider.GetRequiredService(); using var scope = _serviceProvider.CreateScope(); var unitOfWorkManager = scope.ServiceProvider.GetRequiredService(); using var uow = unitOfWorkManager.Begin(requiresNew: true); var plcTaskNo = await _variableService.ReadValueAsync("打码进站PLC任务号"); if (string.IsNullOrEmpty(plcTaskNo?.Content?.Value.SafeString().ToString())) { } else { var myTaskNo = plcTaskNo.Content.Value.SafeString().ToString(); CallMaterialOrder callMaterialOrder = null; try { //根据wms任务号寻找 叫料工单 callMaterialOrder = await callMaterialOrderAppService.GetSingleByFilterAsync(x => x.WmsTaskNo == myTaskNo); if (callMaterialOrder == null) return;//结束 //根据原料标识寻找 作业计划 var workPlanList = await workPlanAppService.GetListByFilterAsync(x => x.DataIdentifier == callMaterialOrder.DataIdentifier); if (workPlanList?.Count == 0) return;//结束 ////TODO:暂时生成产品ID ////var productID = DateTime.Now.ToString("yyyyMMddHHmmssfff"); //var productID = workPlanList.First().PipeSpecCode; //Dictionary keyValuePairs_productID = new Dictionary //{ // { "打码_ProductID", productID}, //}; //var ret = _variableService.WriteValueAsync(keyValuePairs_productID); ////更新为生产中 //foreach (var item in workPlanList) //{ // item.WorkPlanStatus = Domain.Shared.Enums.WorkPlanStatusEnum.生产中; //} //await workPlanRepository.UpdateManyAsync(workPlanList); //得到码值 var code1 = ""; var code2 = ""; var code3 = ""; var pipeSpecCode1 = ""; var pipeSpecCode2 = ""; var pipeSpecCode3 = ""; var new_workPlanList = workPlanList.Where(x => x.ProcessRouteNumber == "切割").ToList(); for (int i = 0; i < new_workPlanList.Count; i++) { if (i == 0) { code1 = new_workPlanList[i].MarkingContent; pipeSpecCode1 = new_workPlanList[i].PipeSpecCode; } if (i == 1) { code2 = new_workPlanList[i].MarkingContent; pipeSpecCode2 = new_workPlanList[i].PipeSpecCode; } if (i == 2) { code3 = new_workPlanList[i].MarkingContent; pipeSpecCode3 = new_workPlanList[i].PipeSpecCode; } } Dictionary keyValuePairs = new Dictionary { { "打码工件1",code1}, { "打码工件2", code2}, { "打码工件3", code3 }, { "打码管段编码1",pipeSpecCode1}, { "打码管段编码2", pipeSpecCode2}, { "打码管段编码3", pipeSpecCode3 }, { "打码管段编码", new_workPlanList.First().PipeSpecCode }, { "打码管段名称", new_workPlanList.First().PipeSectionName }, { "打码原料管型号", new_workPlanList.First().MaterialMode }, { "打码原料标识", new_workPlanList.First().DataIdentifier }, { "打码原料管批次", callMaterialOrder.MaterialBatch },//批次 }; _variableService.WriteValueAsync(keyValuePairs); //TODO:模拟采集参数 keyValuePairs = new Dictionary { { "打码速度", 100}, { "打码质量", 2}, }; var ret2 = _variableService.WriteValueAsync(keyValuePairs); uow.CompleteAsync(); } catch (Exception) { uow.RollbackAsync(); throw; } } } /// /// 请求生成打码产品码信号 /// /// private async Task HanlderForPringBarCodeByCreateProductAsync() { var workPlanAppService = _serviceProvider.GetRequiredService(); var workTaskAppService = _serviceProvider.GetRequiredService(); var workPlanRepository = _serviceProvider.GetRequiredService(); var workTaskRepository = _serviceProvider.GetRequiredService(); var callMaterialOrderAppService = _serviceProvider.GetRequiredService(); using var scope = _serviceProvider.CreateScope(); var unitOfWorkManager = scope.ServiceProvider.GetRequiredService(); using var uow = unitOfWorkManager.Begin(requiresNew: true); var plcTaskNo = await _variableService.ReadValueAsync("打码进站PLC任务号"); if (string.IsNullOrEmpty(plcTaskNo?.Content?.Value.SafeString().ToString())) { } else { var myTaskNo = plcTaskNo.Content.Value.SafeString().ToString(); CallMaterialOrder callMaterialOrder = null; try { //根据wms任务号寻找 叫料工单 callMaterialOrder = await callMaterialOrderAppService.GetSingleByFilterAsync(x => x.WmsTaskNo == myTaskNo); if (callMaterialOrder == null) return;//结束 //根据原料标识寻找 作业计划 var workTaskList = await workTaskAppService.GetListByFilterAsync(x => x.DataIdentifier == callMaterialOrder.DataIdentifier); if (workTaskList?.Count == 0) return;//结束 //更新为生产中 //根据原料标识寻找 作业计划 var workPlanList = await workPlanAppService.GetListByFilterAsync(x => x.DataIdentifier == callMaterialOrder.DataIdentifier); if (workPlanList?.Count == 0) return;//结束 //TODO:暂时生成产品ID //var productID = DateTime.Now.ToString("yyyyMMddHHmmssfff"); var productID = callMaterialOrder.DataIdentifier; Dictionary keyValuePairs_productID = new Dictionary { { "打码_ProductID", productID}, { "CMS反馈请求生成打码产品码信号结果", true}, }; var ret = _variableService.WriteValueAsync(keyValuePairs_productID); //更新 任务 为生产中 var new_workTaskList = workTaskList.Where(x => x.ProcessRouteNumber == "切割").ToList(); foreach (var item in new_workTaskList) { item.WorkPlanStatus = Domain.Shared.Enums.WorkPlanStatusEnum.生产中; } await workTaskRepository.UpdateManyAsync(new_workTaskList); //更新为生产中 var new_workPlanList = workPlanList.Where(x => x.ProcessRouteNumber == "切割").ToList(); foreach (var item in new_workPlanList) { item.WorkPlanStatus = Domain.Shared.Enums.WorkPlanStatusEnum.生产中; } await workPlanRepository.UpdateManyAsync(new_workPlanList); uow.CompleteAsync(); } catch (Exception) { uow.RollbackAsync(); throw; } } } /// /// 请求生成打码产品码信号(值为false的时候) /// /// private async Task HanlderForPringBarCodeByCreateProductWhenFalseAsync() { Dictionary keyValuePairs_productID = new Dictionary { { "CMS反馈请求生成打码产品码信号结果", false}, }; var ret = _variableService.WriteValueAsync(keyValuePairs_productID); } ///// ///// 切割 ///// ///// //private async Task HanlderForCutAsync() //{ // var plcTaskNo = await _variableService.ReadValueAsync("切割进站PLC任务号"); // if (string.IsNullOrEmpty(plcTaskNo?.Content?.Value.SafeString().ToString())) // { // } // else // { // var myTaskNo = plcTaskNo.Content.Value.SafeString().ToString(); // //TODO:暂时先写入 内部变量 // Dictionary keyValuePairs = new Dictionary // { // { "切割位置1", "555555" }, // { "切割位置2", "66666" }, // { "切割位置3", "77777" } // }; // _variableService.WriteValueAsync(keyValuePairs); // //TODO:模拟采集参数 // keyValuePairs = new Dictionary // { // { "切割速度", 99}, // { "切割质量", 1}, // }; // var ret2 = _variableService.WriteValueAsync(keyValuePairs); // //TODO:暂时生成产品ID // //获取上一个工序的产品ID // //根据工序名获取工序对象 // var _workSectionManager = _serviceProvider.GetRequiredService(); // var lastWorkSection = "打码工序"; // var workSection = await _workSectionManager.GetByNameAsync(lastWorkSection); // //获取工单数据(从末工序查询3个产品) // //读取scms_productions表,根据当前时间查询最近3条记录 // var traceManager = _serviceProvider.GetRequiredService(); // GetTracesRequest request = new GetTracesRequest() // { // WorkSectionId = workSection.Id, // }; // TraceModel traceModel = null; // var list = await traceManager.GetTracesAsync(request); // if (list?.Count > 0) // { // //重新排序 // list = list.OrderByDescending(x => x.FinishTime).ToList(); // traceModel = list.First(); // } // //var productID = Guid.NewGuid().ToString(); // var productID = DateTime.Now.ToString("yyyyMMddHHmmssfff"); // if (traceModel != null) // { // productID = traceModel.SerialNumber; // } // keyValuePairs = new Dictionary // { // { "切割_ProductID", productID}, // }; // var ret = _variableService.WriteValueAsync(keyValuePairs); // } //} /// /// 切割 /// /// private async Task HanlderForCutAsync() { var workPlanAppService = _serviceProvider.GetRequiredService(); var workPlanRepository = _serviceProvider.GetRequiredService(); var callMaterialOrderAppService = _serviceProvider.GetRequiredService(); using var scope = _serviceProvider.CreateScope(); var unitOfWorkManager = scope.ServiceProvider.GetRequiredService(); using var uow = unitOfWorkManager.Begin(requiresNew: true); var plcTaskNo = await _variableService.ReadValueAsync("切割进站PLC任务号"); if (string.IsNullOrEmpty(plcTaskNo?.Content?.Value.SafeString().ToString())) { } else { var myTaskNo = plcTaskNo.Content.Value.SafeString().ToString(); CallMaterialOrder callMaterialOrder = null; try { //根据wms任务号寻找 叫料工单 callMaterialOrder = await callMaterialOrderAppService.GetSingleByFilterAsync(x => x.WmsTaskNo == myTaskNo); if (callMaterialOrder == null) return;//结束 //根据原料标识寻找 作业计划 var workPlanList = await workPlanAppService.GetListByFilterAsync(x => x.DataIdentifier == callMaterialOrder.DataIdentifier); if (workPlanList?.Count == 0) return;//结束 ////TODO:暂时生成产品ID ////var productID = DateTime.Now.ToString("yyyyMMddHHmmssfff"); //var productID = workPlanList.First().PipeSpecCode; //Dictionary keyValuePairs_productID = new Dictionary //{ // { "切割_ProductID", productID}, //}; //var ret = _variableService.WriteValueAsync(keyValuePairs_productID); ////更新为生产中 //foreach (var item in workPlanList) //{ // item.WorkPlanStatus = Domain.Shared.Enums.WorkPlanStatusEnum.生产中; //} //await workPlanRepository.UpdateManyAsync(workPlanList); //得到码值 decimal code1 = 0; decimal code2 = 0; decimal code3 = 0; var pipeSpecCode1 = ""; var pipeSpecCode2 = ""; var pipeSpecCode3 = ""; var new_workPlanList = workPlanList.Where(x => x.ProcessRouteNumber == "装配").ToList(); for (int i = 0; i < new_workPlanList.Count; i++) { if (i == 0) { code1 = new_workPlanList[i].CuttingPosition; pipeSpecCode1 = new_workPlanList[i].PipeSpecCode; } if (i == 1) { code2 = new_workPlanList[i].CuttingPosition; pipeSpecCode2 = new_workPlanList[i].PipeSpecCode; } if (i == 2) { code3 = new_workPlanList[i].CuttingPosition; pipeSpecCode3 = new_workPlanList[i].PipeSpecCode; } } Dictionary keyValuePairs = new Dictionary { { "切割位置1",code1}, { "切割位置2", code2}, { "切割位置3", code3 }, { "切割管段编码1",pipeSpecCode1}, { "切割管段编码2", pipeSpecCode2}, { "切割管段编码3", pipeSpecCode3 }, { "切割管段编码", new_workPlanList.First().PipeSpecCode }, { "切割管段名称", new_workPlanList.First().PipeSectionName }, { "切割原料管型号", new_workPlanList.First().MaterialMode }, { "切割原料标识", new_workPlanList.First().DataIdentifier }, { "切割原料管批次", callMaterialOrder.MaterialBatch },//批次 }; _variableService.WriteValueAsync(keyValuePairs); //TODO:模拟采集参数 keyValuePairs = new Dictionary { { "切割速度", 99}, { "切割质量", 1}, }; var ret2 = _variableService.WriteValueAsync(keyValuePairs); uow.CompleteAsync(); } catch (Exception) { uow.RollbackAsync(); throw; } } } /// /// 请求生成切割产品码信号 /// /// private async Task HanlderForCutByCreateProductAsync() { var workPlanAppService = _serviceProvider.GetRequiredService(); var workTaskAppService = _serviceProvider.GetRequiredService(); var workPlanRepository = _serviceProvider.GetRequiredService(); var workTaskRepository = _serviceProvider.GetRequiredService(); var callMaterialOrderAppService = _serviceProvider.GetRequiredService(); using var scope = _serviceProvider.CreateScope(); var unitOfWorkManager = scope.ServiceProvider.GetRequiredService(); using var uow = unitOfWorkManager.Begin(requiresNew: true); var plcTaskNo = await _variableService.ReadValueAsync("切割进站PLC任务号"); if (string.IsNullOrEmpty(plcTaskNo?.Content?.Value.SafeString().ToString())) { } else { var myTaskNo = plcTaskNo.Content.Value.SafeString().ToString(); CallMaterialOrder callMaterialOrder = null; try { //根据wms任务号寻找 叫料工单 callMaterialOrder = await callMaterialOrderAppService.GetSingleByFilterAsync(x => x.WmsTaskNo == myTaskNo); if (callMaterialOrder == null) return;//结束 //根据原料标识寻找 作业计划 var workTaskList = await workTaskAppService.GetListByFilterAsync(x => x.DataIdentifier == callMaterialOrder.DataIdentifier); if (workTaskList?.Count == 0) return;//结束 var new_workTaskList = workTaskList.Where(x => x.ProcessName == "切割工序").ToList(); //更新为生产中 foreach (var item in new_workTaskList) { item.WorkPlanStatus = Domain.Shared.Enums.WorkPlanStatusEnum.生产中; item.Remark = "更新生产中"; } await workTaskRepository.UpdateManyAsync(new_workTaskList); var new_workTaskList_printCode = workTaskList.Where(x => x.ProcessName == "打码工序").ToList(); foreach (var item in new_workTaskList_printCode) { item.WorkPlanStatus = Domain.Shared.Enums.WorkPlanStatusEnum.已完成; item.Remark = "更新已完成"; } await workTaskRepository.UpdateManyAsync(new_workTaskList_printCode); //根据原料标识寻找 作业计划 var workPlanList = await workPlanAppService.GetListByFilterAsync(x => x.DataIdentifier == callMaterialOrder.DataIdentifier); if (workPlanList?.Count == 0) return;//结束 //TODO:暂时生成产品ID //var productID = DateTime.Now.ToString("yyyyMMddHHmmssfff"); var productID = callMaterialOrder.DataIdentifier; Dictionary keyValuePairs_productID = new Dictionary { { "切割_ProductID", productID}, { "CMS反馈请求生成切割产品码信号结果", true}, }; var ret = _variableService.WriteValueAsync(keyValuePairs_productID); var new_workPlanList = workPlanList.Where(x => x.ProcessRouteNumber == "装配").ToList(); //更新为生产中 foreach (var item in new_workPlanList) { item.WorkPlanStatus = Domain.Shared.Enums.WorkPlanStatusEnum.生产中; item.Remark = "更新生产中"; } await workPlanRepository.UpdateManyAsync(new_workPlanList); var new_workPlanList_printCode = workPlanList.Where(x => x.ProcessRouteNumber == "切割").ToList(); foreach (var item in new_workPlanList_printCode) { item.WorkPlanStatus = Domain.Shared.Enums.WorkPlanStatusEnum.已完成; item.Remark = "更新已完成"; } await workPlanRepository.UpdateManyAsync(new_workPlanList_printCode); uow.CompleteAsync(); } catch (Exception) { uow.RollbackAsync(); throw; } } } /// /// 请求生成切割产品码信号(值为false的时候) /// /// private async Task HanlderForCutByCreateProductWhenFlaseAsync() { Dictionary keyValuePairs_productID = new Dictionary { { "CMS反馈请求生成切割产品码信号结果", false}, }; var ret = _variableService.WriteValueAsync(keyValuePairs_productID); } /// /// 装配完工信号=true时 /// /// private async Task HanlderFor装配完工信号Async() { var workPlanAppService = _serviceProvider.GetRequiredService(); var workPlanRepository = _serviceProvider.GetRequiredService(); var callMaterialOrderAppService = _serviceProvider.GetRequiredService(); var pipeSpecCode = await _variableService.ReadValueAsync("装配管段编码"); if (string.IsNullOrEmpty(pipeSpecCode?.Content?.Value.SafeString().ToString())) { } else { var myPipeSpecCode = pipeSpecCode.Content.Value.SafeString().ToString(); CallMaterialOrder callMaterialOrder = null; try { var sharedService = _serviceProvider.GetRequiredService(); var userName = await _variableService.ReadValueAsync("装配人"); MyCurrentUser myCurrentUser = new MyCurrentUser() { UserAccount = userName.Content.Value.SafeString().ToString() }; await sharedService.CompleteAssemblyProcess(_serviceProvider, new Application.Contracts.Dtos.WorkPlan.CompleteAssemblyProcessInput() { PipeSpecCode = myPipeSpecCode, ProcessName = "装配工序" }, myCurrentUser); } catch (Exception ex) { _logger.LogException(ex, LogLevel.Error); } } } /// /// 焊接完工信号=true时 /// /// private async Task HanlderFor焊接完工信号Async() { var workPlanAppService = _serviceProvider.GetRequiredService(); var workPlanRepository = _serviceProvider.GetRequiredService(); var callMaterialOrderAppService = _serviceProvider.GetRequiredService(); var pipeSpecCode = await _variableService.ReadValueAsync("焊接管段编码"); if (string.IsNullOrEmpty(pipeSpecCode?.Content?.Value.SafeString().ToString())) { } else { var myPipeSpecCode = pipeSpecCode.Content.Value.SafeString().ToString(); CallMaterialOrder callMaterialOrder = null; try { var sharedService = _serviceProvider.GetRequiredService(); var userName = await _variableService.ReadValueAsync("焊接人"); MyCurrentUser myCurrentUser = new MyCurrentUser() { UserAccount = userName.Content.Value.SafeString().ToString() }; await sharedService.CompleteAssemblyProcess(_serviceProvider, new Application.Contracts.Dtos.WorkPlan.CompleteAssemblyProcessInput() { PipeSpecCode = myPipeSpecCode, ProcessName = "焊接工序" }, myCurrentUser); } catch (Exception ex) { _logger.LogException(ex, LogLevel.Error); } } } /// /// 法兰冲码完工信号=true时 /// /// private async Task HanlderFor法兰冲码完工信号Async() { var txt = "法兰冲码"; var workPlanAppService = _serviceProvider.GetRequiredService(); var workPlanRepository = _serviceProvider.GetRequiredService(); var callMaterialOrderAppService = _serviceProvider.GetRequiredService(); var pipeSpecCode = await _variableService.ReadValueAsync($"{txt}管段编码"); if (string.IsNullOrEmpty(pipeSpecCode?.Content?.Value.SafeString().ToString())) { } else { var myPipeSpecCode = pipeSpecCode.Content.Value.SafeString().ToString(); CallMaterialOrder callMaterialOrder = null; try { var sharedService = _serviceProvider.GetRequiredService(); var userName = await _variableService.ReadValueAsync($"{txt}人"); MyCurrentUser myCurrentUser = new MyCurrentUser() { UserAccount = userName.Content.Value.SafeString().ToString() }; await sharedService.SendFlangeCode_CompleteAssemblyProcess(_serviceProvider, new Application.Contracts.Dtos.WorkPlan.CompleteAssemblyProcessInput() { PipeSpecCode = myPipeSpecCode, ProcessName = $"{txt}工序" }, myCurrentUser); } catch (Exception ex) { _logger.LogException(ex, LogLevel.Error); } } } /// /// 完工信号=false时 /// /// private async Task HanlderFor完工信号WhenFalseAsync(string processName) { try { var sharedService = _serviceProvider.GetRequiredService(); await sharedService.CompleteHandleOutStoreFinish(_serviceProvider, processName, false); } catch (Exception) { } } } }