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;
|
|
namespace CMS.Plugin.PipeLineLems.ProjectService
|
{
|
/// <summary>
|
/// 工程服务,和工程关联的后台服务,当<see cref="IProjectServiceRunner"/>以当前Key调用时会被执行
|
/// </summary>
|
public class PipeLineLemsProjectService : BaseProjectService
|
{
|
private IServiceProvider _serviceProvider;
|
private readonly ILogger<PipeLineLemsProjectService> _logger;
|
private readonly IVariableDataCache _variableDataCache;
|
|
|
/// <summary>
|
/// 变量服务
|
/// </summary>
|
private readonly VariableService _variableService;
|
private FlowVariableChannelListener _channelListener;
|
private Dictionary<string, string> _monitorVariableNames;
|
|
/// <summary>
|
/// 服务的Key,唯一,供<see cref="IProjectServiceRunner"/>使用
|
/// </summary>
|
public override string Key => "PipeLineLems";
|
|
/// <summary>
|
/// 服务描述,显示在服务列表UI上的名称
|
/// </summary>
|
public override string Description => "PipeLineLems服务";
|
|
/// <summary>
|
/// 启用授权
|
/// </summary>
|
public override bool AuthRequired => true;
|
|
/// <summary>
|
/// Initializes a new instance of the <see cref="PipeLineLemsProjectService"/> class.
|
/// </summary>
|
/// <param name="logger">The logger.</param>
|
/// <param name="variableDataCache">The variable data cache.</param>
|
public PipeLineLemsProjectService(
|
VariableService variableService,
|
IServiceProvider serviceProvider, ILogger<PipeLineLemsProjectService> logger, IVariableDataCache variableDataCache)
|
{
|
_serviceProvider = serviceProvider;
|
_logger = logger;
|
_variableDataCache = variableDataCache;
|
_variableService = variableService;
|
}
|
|
/// <summary>
|
/// 开启服务
|
/// </summary>
|
/// <param name="serviceProvider">具有工程上下文的实例</param>
|
public override async Task StartAsync(IServiceProvider serviceProvider)
|
{
|
if (State == ProjectServiceState.Started)
|
{
|
return;
|
}
|
|
// 监听变量
|
_monitorVariableNames = new Dictionary<string, string>
|
{
|
{ "打码进站信号", "打码进站信号(描述)" },
|
{ "请求生成打码产品码信号", "请求生成打码产品码信号(描述)" },
|
{ "请求生成切割产品码信号", "请求生成切割产品码信号(描述)" },
|
{ "切割进站信号", "切割进站信号(描述)" },
|
|
{ "装配完工信号", "装配完工信号(描述)" },
|
{ "焊接完工信号", "焊接完工信号(描述)" },
|
};
|
|
// 创建通道监听
|
_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);
|
}
|
|
/// <summary>
|
/// 停止服务
|
/// </summary>
|
/// <param name="serviceProvider">具有工程上下文的实例</param>
|
public override async Task StopAsync(IServiceProvider serviceProvider)
|
{
|
if (_channelListener != null)
|
{
|
// 释放监听
|
_channelListener.TagChanged -= OnTagValueChanged;
|
_channelListener.Token.Dispose();
|
_channelListener = null;
|
}
|
|
// 使用后台作业异步处理
|
//await _serviceProvider.GetRequiredService<IBackgroundJobManager>().EnqueueAsync(new PipeLineLemsArgs
|
//{
|
// Subject = "PipeLineLems_Subject",
|
// Body = "PipeLineLems_Body",
|
//});
|
|
|
await base.StopAsync(serviceProvider);
|
}
|
|
/// <summary>
|
/// Called when [tag value changed].
|
/// </summary>
|
/// <param name="sender">The sender.</param>
|
/// <param name="e">The <see cref="TagChangedEventArgs"/> instance containing the event data.</param>
|
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("焊接");
|
});
|
}
|
}
|
}
|
}
|
|
/// <summary>
|
/// Processes the asynchronous.
|
/// </summary>
|
private async Task ProcessAsync()
|
{
|
using var scope = _serviceProvider.CreateScope();
|
var unitOfWorkManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
|
using var uow = unitOfWorkManager.Begin(requiresNew: true);
|
var mytestentitynameRepository = scope.ServiceProvider.GetRequiredService<IMyTestEntityNameRepository>();
|
var count = await mytestentitynameRepository.GetCountAsync();
|
|
// 如果有更新数据库操作,需提交保存
|
// await uow.SaveChangesAsync();
|
|
_logger.LogInformation($"ProcessAsync,Count={count}");
|
}
|
|
/// <summary>
|
/// Executes the external API.
|
/// </summary>
|
private async Task ExecuteExternalApiAsync()
|
{
|
try
|
{
|
await _serviceProvider.GetRequiredService<IPipeLineLemsExternalApi>().CreateAsync(new MyTestEntityNameCreateDto
|
{
|
Name = "MyTestEntityName_Name",
|
Code = "MyTestEntityName_Code",
|
});
|
}
|
catch (Exception e)
|
{
|
_logger.LogException(e);
|
}
|
}
|
|
/// <summary>
|
/// 打码进站信号
|
/// </summary>
|
/// <returns></returns>
|
private async Task HanlderForPringBarCodeAsync()
|
{
|
|
var workPlanAppService = _serviceProvider.GetRequiredService<IWorkPlanAppService>();
|
var workPlanRepository = _serviceProvider.GetRequiredService<IWorkPlanRepository>();
|
var callMaterialOrderAppService = _serviceProvider.GetRequiredService<ICallMaterialOrderAppService>();
|
|
using var scope = _serviceProvider.CreateScope();
|
var unitOfWorkManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
|
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<string, object?> keyValuePairs_productID = new Dictionary<string, object?>
|
//{
|
// { "打码_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<string, object?> keyValuePairs = new Dictionary<string, object?>
|
{
|
{ "打码工件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<string, object?>
|
{
|
{ "打码速度", 100},
|
{ "打码质量", 2},
|
};
|
var ret2 = _variableService.WriteValueAsync(keyValuePairs);
|
|
|
|
|
uow.CompleteAsync();
|
}
|
catch (Exception)
|
{
|
uow.RollbackAsync();
|
throw;
|
}
|
}
|
}
|
|
/// <summary>
|
/// 请求生成打码产品码信号
|
/// </summary>
|
/// <returns></returns>
|
private async Task HanlderForPringBarCodeByCreateProductAsync()
|
{
|
|
var workPlanAppService = _serviceProvider.GetRequiredService<IWorkPlanAppService>();
|
var workPlanRepository = _serviceProvider.GetRequiredService<IWorkPlanRepository>();
|
var callMaterialOrderAppService = _serviceProvider.GetRequiredService<ICallMaterialOrderAppService>();
|
|
using var scope = _serviceProvider.CreateScope();
|
var unitOfWorkManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
|
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 = callMaterialOrder.DataIdentifier;
|
Dictionary<string, object?> keyValuePairs_productID = new Dictionary<string, object?>
|
{
|
{ "打码_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.生产中;
|
}
|
await workPlanRepository.UpdateManyAsync(new_workPlanList);
|
|
|
uow.CompleteAsync();
|
}
|
catch (Exception)
|
{
|
uow.RollbackAsync();
|
throw;
|
}
|
}
|
}
|
|
/// <summary>
|
/// 请求生成打码产品码信号(值为false的时候)
|
/// </summary>
|
/// <returns></returns>
|
private async Task HanlderForPringBarCodeByCreateProductWhenFalseAsync()
|
{
|
Dictionary<string, object?> keyValuePairs_productID = new Dictionary<string, object?>
|
{
|
{ "CMS反馈请求生成打码产品码信号结果", false},
|
};
|
var ret = _variableService.WriteValueAsync(keyValuePairs_productID);
|
}
|
|
|
///// <summary>
|
///// 切割
|
///// </summary>
|
///// <returns></returns>
|
//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<string, object?> keyValuePairs = new Dictionary<string, object?>
|
// {
|
// { "切割位置1", "555555" },
|
// { "切割位置2", "66666" },
|
// { "切割位置3", "77777" }
|
// };
|
// _variableService.WriteValueAsync(keyValuePairs);
|
|
// //TODO:模拟采集参数
|
// keyValuePairs = new Dictionary<string, object?>
|
// {
|
// { "切割速度", 99},
|
// { "切割质量", 1},
|
// };
|
// var ret2 = _variableService.WriteValueAsync(keyValuePairs);
|
|
// //TODO:暂时生成产品ID
|
// //获取上一个工序的产品ID
|
// //根据工序名获取工序对象
|
// var _workSectionManager = _serviceProvider.GetRequiredService<IWorkSectionManager>();
|
// var lastWorkSection = "打码工序";
|
// var workSection = await _workSectionManager.GetByNameAsync(lastWorkSection);
|
|
// //获取工单数据(从末工序查询3个产品)
|
// //读取scms_productions表,根据当前时间查询最近3条记录
|
// var traceManager = _serviceProvider.GetRequiredService<ITraceProvider>();
|
// 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<string, object?>
|
// {
|
// { "切割_ProductID", productID},
|
// };
|
// var ret = _variableService.WriteValueAsync(keyValuePairs);
|
// }
|
//}
|
|
/// <summary>
|
/// 切割
|
/// </summary>
|
/// <returns></returns>
|
private async Task HanlderForCutAsync()
|
{
|
|
var workPlanAppService = _serviceProvider.GetRequiredService<IWorkPlanAppService>();
|
var workPlanRepository = _serviceProvider.GetRequiredService<IWorkPlanRepository>();
|
var callMaterialOrderAppService = _serviceProvider.GetRequiredService<ICallMaterialOrderAppService>();
|
|
using var scope = _serviceProvider.CreateScope();
|
var unitOfWorkManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
|
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<string, object?> keyValuePairs_productID = new Dictionary<string, object?>
|
//{
|
// { "切割_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<string, object?> keyValuePairs = new Dictionary<string, object?>
|
{
|
{ "切割位置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<string, object?>
|
{
|
{ "切割速度", 99},
|
{ "切割质量", 1},
|
};
|
var ret2 = _variableService.WriteValueAsync(keyValuePairs);
|
|
|
|
|
uow.CompleteAsync();
|
}
|
catch (Exception)
|
{
|
uow.RollbackAsync();
|
throw;
|
}
|
}
|
}
|
|
/// <summary>
|
/// 请求生成切割产品码信号
|
/// </summary>
|
/// <returns></returns>
|
private async Task HanlderForCutByCreateProductAsync()
|
{
|
|
var workPlanAppService = _serviceProvider.GetRequiredService<IWorkPlanAppService>();
|
var workPlanRepository = _serviceProvider.GetRequiredService<IWorkPlanRepository>();
|
var callMaterialOrderAppService = _serviceProvider.GetRequiredService<ICallMaterialOrderAppService>();
|
|
using var scope = _serviceProvider.CreateScope();
|
var unitOfWorkManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
|
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 = callMaterialOrder.DataIdentifier;
|
Dictionary<string, object?> keyValuePairs_productID = new Dictionary<string, object?>
|
{
|
{ "切割_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;
|
}
|
}
|
}
|
|
/// <summary>
|
/// 请求生成切割产品码信号(值为false的时候)
|
/// </summary>
|
/// <returns></returns>
|
private async Task HanlderForCutByCreateProductWhenFlaseAsync()
|
{
|
|
Dictionary<string, object?> keyValuePairs_productID = new Dictionary<string, object?>
|
{
|
{ "CMS反馈请求生成切割产品码信号结果", false},
|
};
|
var ret = _variableService.WriteValueAsync(keyValuePairs_productID);
|
}
|
|
|
|
/// <summary>
|
/// 装配完工信号=true时
|
/// </summary>
|
/// <returns></returns>
|
private async Task HanlderFor装配完工信号Async()
|
{
|
|
var workPlanAppService = _serviceProvider.GetRequiredService<IWorkPlanAppService>();
|
var workPlanRepository = _serviceProvider.GetRequiredService<IWorkPlanRepository>();
|
var callMaterialOrderAppService = _serviceProvider.GetRequiredService<ICallMaterialOrderAppService>();
|
|
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<SharedService>();
|
var userName = await _variableService.ReadValueAsync("装配人");
|
MyCurrentUser myCurrentUser = new MyCurrentUser()
|
{
|
UserAccount = userName.Content.Value.SafeString().ToString()
|
};
|
sharedService.CompleteAssemblyProcess(_serviceProvider, new Application.Contracts.Dtos.WorkPlan.CompleteAssemblyProcessInput() { PipeSpecCode = myPipeSpecCode, ProcessName="装配工序" }, myCurrentUser);
|
|
}
|
catch (Exception)
|
{
|
|
}
|
}
|
}
|
|
/// <summary>
|
/// 焊接完工信号=true时
|
/// </summary>
|
/// <returns></returns>
|
private async Task HanlderFor焊接完工信号Async()
|
{
|
|
var workPlanAppService = _serviceProvider.GetRequiredService<IWorkPlanAppService>();
|
var workPlanRepository = _serviceProvider.GetRequiredService<IWorkPlanRepository>();
|
var callMaterialOrderAppService = _serviceProvider.GetRequiredService<ICallMaterialOrderAppService>();
|
|
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<SharedService>();
|
var userName = await _variableService.ReadValueAsync("焊接人");
|
MyCurrentUser myCurrentUser = new MyCurrentUser()
|
{
|
UserAccount = userName.Content.Value.SafeString().ToString()
|
};
|
sharedService.CompleteAssemblyProcess(_serviceProvider, new Application.Contracts.Dtos.WorkPlan.CompleteAssemblyProcessInput() { PipeSpecCode = myPipeSpecCode, ProcessName = "焊接工序" }, myCurrentUser);
|
|
}
|
catch (Exception)
|
{
|
|
}
|
}
|
}
|
|
/// <summary>
|
/// 完工信号=false时
|
/// </summary>
|
/// <returns></returns>
|
private async Task HanlderFor完工信号WhenFalseAsync(string processName)
|
{
|
try
|
{
|
var sharedService = _serviceProvider.GetRequiredService<SharedService>();
|
await sharedService.CompleteHandleOutStoreFinish(_serviceProvider, processName, false);
|
}
|
catch (Exception)
|
{
|
|
|
}
|
}
|
}
|
}
|