mqtt超时
This commit is contained in:
parent
dc37fe2496
commit
7ae1cefc11
@ -51,7 +51,7 @@ public class WorkOrderProgressController : BaseController
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 工单list (未完成的)
|
||||
/// 工单list (未完成的)
|
||||
/// </summary>
|
||||
/// <param name="today"></param>
|
||||
/// <param name="LineCode"></param>
|
||||
@ -107,6 +107,29 @@ public class WorkOrderProgressController : BaseController
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
|
||||
//TODO 暂停某个工单
|
||||
[HttpGet("pause_workorder")]
|
||||
public IActionResult PauseWorkOrder(string workorder)
|
||||
{
|
||||
if (string.IsNullOrEmpty(workorder)) return SUCCESS(null);
|
||||
var response = workorderProgressService.PauseWorkOrder(workorder);
|
||||
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
|
||||
//TODO 恢复某个工单
|
||||
[HttpGet("recover_workorder")]
|
||||
public IActionResult RecoverWorkOrder(string workorder)
|
||||
{
|
||||
if (string.IsNullOrEmpty(workorder)) return SUCCESS(null);
|
||||
var response = workorderProgressService.RecoverWorkOrder(workorder);
|
||||
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
|
||||
//TODO 完成某一个工单
|
||||
[HttpGet("finish_workorder")]
|
||||
public IActionResult FinishWorkOrder(string workorder)
|
||||
@ -117,6 +140,22 @@ public class WorkOrderProgressController : BaseController
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TODO 完成 工单
|
||||
/// </summary>
|
||||
/// <param name="workorder"></param>
|
||||
/// <returns></returns.
|
||||
[HttpGet("finish_workorder2")]
|
||||
public IActionResult FinishWorkorder(string workorder, int finish_num)
|
||||
{
|
||||
if (string.IsNullOrEmpty(workorder)) return SUCCESS(null);
|
||||
var response = workorderProgressService.FinishWorkorder(workorder, finish_num);
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//TODO 获取某条产线 某个日期,某个班组的生产中的工单 上位机接口 (废弃)
|
||||
[HttpGet("get_producting_workorder")]
|
||||
public IActionResult GetProductingWorkorder(string line_code, DateTime handleDate)
|
||||
@ -169,18 +208,7 @@ public class WorkOrderProgressController : BaseController
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// TODO 完成 工单
|
||||
/// </summary>
|
||||
/// <param name="workorder"></param>
|
||||
/// <returns></returns.
|
||||
[HttpGet("finish_workorder2")]
|
||||
public IActionResult FinishWorkorder(string workorder, int finish_num)
|
||||
{
|
||||
if (string.IsNullOrEmpty(workorder)) return SUCCESS(null);
|
||||
var response = workorderProgressService.FinishWorkorder(workorder, finish_num);
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//TODO 获取工单进度
|
||||
@ -230,5 +258,14 @@ public class WorkOrderProgressController : BaseController
|
||||
}
|
||||
|
||||
|
||||
//TODO 当天每小时目标产量和实际产量
|
||||
[HttpGet("get_hourly_production")]
|
||||
public IActionResult GetHourlyProduction(string groupCode)
|
||||
{
|
||||
if (string.IsNullOrEmpty(groupCode)) throw new CustomException("groupCode is null");
|
||||
var response = workorderProgressService.GetHourlyProduction(groupCode);
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -156,7 +156,7 @@ namespace DOAN.Admin.WebApi.Controllers
|
||||
[AllowAnonymous]
|
||||
public IActionResult ExportData([FromQuery] DateTime exportDate)
|
||||
{
|
||||
if(exportDate == null || exportDate == DateTime.MinValue)
|
||||
if(exportDate == DateTime.MinValue)
|
||||
{
|
||||
return ToResponse(ApiResult.Error("导出失败,日期不能为空"));
|
||||
}
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using DOAN.Model.MES.product;
|
||||
using DOAN.Model.MES.product.Dto;
|
||||
|
||||
|
||||
using DOAN.Service.MES.product.IService;
|
||||
using DOAN.Service.MES.product;
|
||||
using DOAN.Admin.WebApi.Filters;
|
||||
|
||||
@ -44,7 +44,7 @@ namespace DOAN.WebApi.Controllers.Mobile.product
|
||||
{
|
||||
var response = printAndReportWorkService.CheckBoxInspectionLabel(workorder, box_label);
|
||||
return SUCCESS(response);
|
||||
return SUCCESS(true);
|
||||
|
||||
}
|
||||
|
||||
//TODO 校验首标签
|
||||
|
||||
@ -8,9 +8,9 @@
|
||||
},
|
||||
"dbConfigs": [
|
||||
{
|
||||
// "Conn": "Data Source=139.224.232.211;User ID=root;Password=doantech123;Initial Catalog=GXAssembly;Port=3308",
|
||||
// "Conn": "Data Source=139.224.232.211;User ID=root;Password=doantech123;Initial Catalog=GXAssembly;Port=3308",
|
||||
//"Conn": "Data Source=118.25.48.201;User ID=root;Password=123456;Initial Catalog=gxassembly;Port=3306;AllowLoadLocalInfile=true",
|
||||
"Conn": "Data Source=192.168.1.48;User ID=root;Password=123456;Initial Catalog=GXAssembly;Port=3306;AllowLoadLocalInfile=true",
|
||||
"Conn": "Data Source=192.168.1.48;User ID=root;Password=123456;Initial Catalog=GXAssembly;Port=3306;AllowLoadLocalInfile=true",
|
||||
// "Conn": "Data Source=127.0.0.1;User ID=root;Password=123456;Initial Catalog=GXAssembly;Port=3306",
|
||||
//"Conn": "Data Source=192.168.50.163;User ID=root;Password=123456;Initial Catalog=GXAssembly;Port=3306",
|
||||
"DbType": 0, //数据库类型 MySql = 0, SqlServer = 1, Oracle = 3,PgSql = 4
|
||||
@ -47,6 +47,13 @@
|
||||
"DbType": 4, //数据库类型 MySql = 0, SqlServer = 1, Oracle = 3,PgSql = 4
|
||||
"ConfigId": "4", //多租户唯一标识
|
||||
"IsAutoCloseConnection": true
|
||||
},
|
||||
// gxassembly_lmes
|
||||
{
|
||||
"Conn": "Data Source=192.168.1.48;User ID=root;Password=123456;Initial Catalog=gxassembly_lmes;Port=3306;AllowLoadLocalInfile=true",
|
||||
"DbType": 0, //数据库类型 MySql = 0, SqlServer = 1, Oracle = 3,PgSql = 4
|
||||
"ConfigId": "5", //多租户唯一标识
|
||||
"IsAutoCloseConnection": true
|
||||
}
|
||||
//...下面添加更多的数据库源
|
||||
],
|
||||
|
||||
53
DOAN.Model/MES/product/ProWorkorderStatus.cs
Normal file
53
DOAN.Model/MES/product/ProWorkorderStatus.cs
Normal file
@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DOAN.Model.MES.product
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 生产工单
|
||||
/// </summary>
|
||||
[SugarTable("pro_workorder_status")]
|
||||
public class ProWorkorderStatus
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "id", IsPrimaryKey = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 工单号
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "fk_workorder_code")]
|
||||
public string FkWorkorderCode { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 状态(1 init,2 start 3 end 4 pause)
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "status")]
|
||||
public int Status { get; set; }
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 状态更改时间
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "change_time")]
|
||||
public DateTime ChangeTime { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "created_time")]
|
||||
public DateTime CreatedTime { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,12 +1,13 @@
|
||||
using System;
|
||||
using DOAN.Model.JobKanban;
|
||||
using DOAN.Model.mes.echarts;
|
||||
using DOAN.Model.MES.base_;
|
||||
using DOAN.Model.MES.product;
|
||||
using DOAN.Model.MES.product.Dto;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DOAN.Model.JobKanban;
|
||||
using DOAN.Model.MES.base_;
|
||||
using DOAN.Model.MES.product;
|
||||
using DOAN.Model.MES.product.Dto;
|
||||
namespace DOAN.Service.JobKanban.IService
|
||||
{
|
||||
public interface IWorkorderProgressService
|
||||
@ -26,6 +27,10 @@ namespace DOAN.Service.JobKanban.IService
|
||||
|
||||
KanbanInfo GetKanbanNum(DateTime today, string line_code, string group_code);
|
||||
Task<int> StartWorkOrder(string workorder);
|
||||
|
||||
|
||||
int PauseWorkOrder(string workorder);
|
||||
int RecoverWorkOrder(string workorder);
|
||||
int FinishWorkOrder(string workorder);
|
||||
ProWorkorder GetProductingWorkorder(string line_code, DateTime handleDate);
|
||||
int AddLabelLog(string labelContext, string workOrder);
|
||||
@ -44,5 +49,8 @@ namespace DOAN.Service.JobKanban.IService
|
||||
List<ProReportworkDetail> GetWorkOrderScanCodeInfo(string workorder);
|
||||
|
||||
bool SwitchWorkOrderCheckLabel(string pre_workorder);
|
||||
|
||||
|
||||
EchartsOptions GetHourlyProduction(string groupCode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
using DOAN.Infrastructure.Helper;
|
||||
using DOAN.Model.JobKanban;
|
||||
using DOAN.Model.mes.echarts;
|
||||
using DOAN.Model.MES.base_;
|
||||
using DOAN.Model.MES.group;
|
||||
using DOAN.Model.MES.mm;
|
||||
using DOAN.Model.MES.product;
|
||||
using DOAN.Model.MES.product.Dto;
|
||||
@ -14,6 +16,7 @@ using Mapster;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using SqlSugar.SplitTableExtensions;
|
||||
using System.Data;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -162,59 +165,69 @@ public class WorkorderProgressService : BaseService<ProWorkorder>, IWorkorderPro
|
||||
//TODO 拼接MQTT消息,发送给设备,工单信息和配方信息
|
||||
var spec = handleWorkorder.Specification;
|
||||
|
||||
var RecipeMesg = Context.Queryable<PfRefProductRecipe>()
|
||||
.LeftJoin<PfRecipeVersion>((rpr, r) => rpr.RecipeCode == r.RecipeCode)
|
||||
.Where((rpr, r) => SqlFunc.Like(spec, rpr.RecipeCode + "%"))
|
||||
.Where((rpr, r) => r.Status == 1)
|
||||
.Select((rpr, r) => new
|
||||
{
|
||||
RecipeCode = r.RecipeCode,
|
||||
Version = r.Version,
|
||||
ParamList = SqlFunc.Subqueryable<PfRecipeParameters>()
|
||||
.Where(it => it.RecipeCode == r.RecipeCode && it.Version == r.Version)
|
||||
.ToList(),
|
||||
// 添加匹配长度用于排序
|
||||
MatchLength = rpr.RecipeCode.Length
|
||||
})
|
||||
.MergeTable()
|
||||
.OrderByDescending(x => x.MatchLength) // 按匹配长度降序排列
|
||||
.First(); // 取第一个(匹配最长的)
|
||||
//var RecipeMesg = Context.Queryable<PfRefProductRecipe>()
|
||||
// .LeftJoin<PfRecipeVersion>((rpr, r) => rpr.RecipeCode == r.RecipeCode)
|
||||
// .Where((rpr, r) => SqlFunc.Like(spec, rpr.RecipeCode + "%"))
|
||||
// .Where((rpr, r) => r.Status == 1)
|
||||
// .Select((rpr, r) => new
|
||||
// {
|
||||
// RecipeCode = r.RecipeCode,
|
||||
// Version = r.Version,
|
||||
// ParamList = SqlFunc.Subqueryable<PfRecipeParameters>()
|
||||
// .Where(it => it.RecipeCode == r.RecipeCode && it.Version == r.Version)
|
||||
// .ToList(),
|
||||
// // 添加匹配长度用于排序
|
||||
// MatchLength = rpr.RecipeCode.Length
|
||||
// })
|
||||
// .MergeTable()
|
||||
// .OrderByDescending(x => x.MatchLength) // 按匹配长度降序排列
|
||||
// .First(); // 取第一个(匹配最长的)
|
||||
|
||||
|
||||
// 合并两个对象为匿名对象
|
||||
var combinedObject = new
|
||||
{
|
||||
WorkorderInfo = handleWorkorder,
|
||||
RecipeInfo = RecipeMesg
|
||||
// RecipeInfo = RecipeMesg
|
||||
};
|
||||
|
||||
|
||||
string jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(combinedObject, Newtonsoft.Json.Formatting.Indented);
|
||||
//插入配方派发日志
|
||||
if (RecipeMesg != null && !string.IsNullOrEmpty(RecipeMesg.RecipeCode))
|
||||
{
|
||||
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();
|
||||
//if (RecipeMesg != null && !string.IsNullOrEmpty(RecipeMesg.RecipeCode))
|
||||
//{
|
||||
// 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("192.168.50.163", 1883);
|
||||
|
||||
// 连接
|
||||
await _mqttHelper.ConnectAsync();
|
||||
|
||||
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(2)); // 总超时10秒
|
||||
var connectTask = _mqttHelper.ConnectAsync();
|
||||
var timeoutTask = Task.Delay(5000, cts.Token); // 5秒连接超时
|
||||
|
||||
var completedTask = await Task.WhenAny(connectTask, timeoutTask);
|
||||
if (completedTask == timeoutTask)
|
||||
{
|
||||
throw new TimeoutException("连接MQTT服务器超时");
|
||||
}
|
||||
await connectTask; // 确保没有异常
|
||||
|
||||
// 发送多条消息
|
||||
string line = handleWorkorder.LineCode ==null?"-1": handleWorkorder.LineCode;
|
||||
await _mqttHelper.PublishMessageAsync("MES/Workorder/Start/handleWorkorder/"+ line, jsonString);
|
||||
string line = handleWorkorder.LineCode == null ? "-1" : handleWorkorder.LineCode;
|
||||
await _mqttHelper.PublishMessageAsync("MES/Workorder/Start/handleWorkorder/" + line, jsonString);
|
||||
|
||||
// 断开连接
|
||||
await _mqttHelper.DisconnectAsync();
|
||||
@ -260,7 +273,7 @@ public class WorkorderProgressService : BaseService<ProWorkorder>, IWorkorderPro
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -272,13 +285,91 @@ public class WorkorderProgressService : BaseService<ProWorkorder>, IWorkorderPro
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 暂停工单
|
||||
/// </summary>
|
||||
/// <param name="workorder"></param>
|
||||
/// <returns></returns>
|
||||
public int PauseWorkOrder(string workorder)
|
||||
{
|
||||
int result = 0;
|
||||
UseTran2(() =>
|
||||
{
|
||||
ProWorkorderStatus proWorkorderStatus = new ProWorkorderStatus();
|
||||
proWorkorderStatus.FkWorkorderCode = workorder;
|
||||
proWorkorderStatus.Status = 4;
|
||||
proWorkorderStatus.ChangeTime = DateTime.Now;
|
||||
proWorkorderStatus.CreatedTime = DateTime.Now;
|
||||
|
||||
Context.Insertable(proWorkorderStatus).ExecuteCommand();
|
||||
|
||||
|
||||
result = Context.Updateable<ProWorkorder>()
|
||||
.SetColumns(it => it.Status == 4)
|
||||
.SetColumns(it => it.EndTime == DateTime.Now)
|
||||
.Where(it => it.Workorder == workorder).ExecuteCommand();
|
||||
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 恢复工单
|
||||
/// </summary>
|
||||
/// <param name="workorder"></param>
|
||||
/// <returns></returns>
|
||||
public int RecoverWorkOrder(string workorder)
|
||||
{
|
||||
int result = 0;
|
||||
UseTran2(() =>
|
||||
{
|
||||
ProWorkorderStatus proWorkorderStatus = new ProWorkorderStatus();
|
||||
proWorkorderStatus.FkWorkorderCode = workorder;
|
||||
proWorkorderStatus.Status = 5;
|
||||
proWorkorderStatus.ChangeTime = DateTime.Now;
|
||||
proWorkorderStatus.CreatedTime = DateTime.Now;
|
||||
|
||||
Context.Insertable(proWorkorderStatus).ExecuteCommand();
|
||||
|
||||
|
||||
result = Context.Updateable<ProWorkorder>()
|
||||
.SetColumns(it => it.Status == 5)
|
||||
.SetColumns(it => it.EndTime == DateTime.Now)
|
||||
.Where(it => it.Workorder == workorder).ExecuteCommand();
|
||||
|
||||
});
|
||||
return result;
|
||||
}
|
||||
/// <summary>
|
||||
/// 工单完成
|
||||
/// </summary>
|
||||
/// <param name="workorder"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
public int FinishWorkOrder(string workorder)
|
||||
{
|
||||
return Context.Updateable<ProWorkorder>()
|
||||
.SetColumns(it => it.Status == 3)
|
||||
.SetColumns(it => it.EndTime == DateTime.Now)
|
||||
.Where(it => it.Workorder == workorder).ExecuteCommand();
|
||||
int result = 0;
|
||||
UseTran2(() =>
|
||||
{
|
||||
ProWorkorderStatus proWorkorderStatus = new ProWorkorderStatus();
|
||||
proWorkorderStatus.FkWorkorderCode = workorder;
|
||||
proWorkorderStatus.Status = 3;
|
||||
proWorkorderStatus.ChangeTime = DateTime.Now;
|
||||
proWorkorderStatus.CreatedTime = DateTime.Now;
|
||||
|
||||
|
||||
Context.Insertable(proWorkorderStatus).ExecuteCommand();
|
||||
|
||||
result = Context.Updateable<ProWorkorder>()
|
||||
.SetColumns(it => it.Status == 3)
|
||||
.SetColumns(it => it.EndTime == DateTime.Now)
|
||||
.Where(it => it.Workorder == workorder).ExecuteCommand();
|
||||
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public ProWorkorder GetProductingWorkorder(string line_code, DateTime handleDate)
|
||||
{
|
||||
@ -496,4 +587,149 @@ public class WorkorderProgressService : BaseService<ProWorkorder>, IWorkorderPro
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public EchartsOptions GetHourlyProduction(string groupCode)
|
||||
{
|
||||
|
||||
EchartsOptions echartsOptions = new EchartsOptions();
|
||||
|
||||
echartsOptions.Title = new EchartsTitle("今日各组实时完工数与计划完工柱状图", "获取今日各组实时每小时完工数柱状图");
|
||||
|
||||
//横轴 8:00 20:00 每60分钟累加一次
|
||||
// 1.获取这个班组工作时间
|
||||
GroupShift Shifts = Context.Queryable<GroupSchedule>().LeftJoin<GroupShift>((sc, sh) => sc.FkShift == sh.Id)
|
||||
.Where((sc, sh) => sc.ScheduleDate == DateTime.Today && sc.GroupCode == groupCode).Select((sc, sh) => sh).First();
|
||||
if (Shifts == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// 处理每小时间隔
|
||||
int intervals = (int)Math.Ceiling((Shifts.EndTime - Shifts.StartTime).Value.TotalMinutes / 60);
|
||||
intervals++;
|
||||
// 获取今天的日期
|
||||
DateTime today = DateTime.Today;
|
||||
// 定义一个表示8小时的时间间隔
|
||||
TimeSpan eightOClock = new TimeSpan(Shifts.StartTime.Value.Hour, Shifts.StartTime.Value.Minute, Shifts.StartTime.Value.Second);
|
||||
// 将今天的日期与8点的时间间隔相加
|
||||
DateTime todayAtEight = today + eightOClock;
|
||||
DateTime[] dateTimeArray = new DateTime[intervals];
|
||||
for (int i = 0; i < intervals; i++)
|
||||
{
|
||||
TimeSpan spanItem = new TimeSpan(0, 10 * i, 0);// 60分钟间隔
|
||||
DateTime TodayItem = todayAtEight + spanItem;
|
||||
dateTimeArray[i] = TodayItem;
|
||||
}
|
||||
EchartsXAxis XAxis = new EchartsXAxis();
|
||||
XAxis.Data = dateTimeArray.Select(it => it.ToString("HH:mm")).ToList();
|
||||
echartsOptions.XAxis = XAxis;
|
||||
//2 系列值-这组 今日实时完成数(60分钟)
|
||||
EchartsSeries echartsSeries = new EchartsSeries();
|
||||
echartsSeries.Name = groupCode + "组今日实时完成数(每60分钟)";
|
||||
echartsSeries.Type = "bar";
|
||||
List<EchartsSeriesData> echartsSeriesDatas = new List<EchartsSeriesData>();
|
||||
//UNIX_TIMESTAMP(timestamp) 把 timestamp 转换为自 Unix 纪元以来的秒数。
|
||||
//FLOOR(... / 600) 将该时间戳除以600(10分钟的秒数),然后向下取整到最接近的整数。
|
||||
//*600 再次乘以600,以获得每个10分钟周期开始的时间戳。
|
||||
//FROM_UNIXTIME(...) 将处理后的时间戳转换回日期时间格式,以便在结果集中显示。
|
||||
|
||||
string year = DateTime.Today.Year.ToString("D4");
|
||||
string month = DateTime.Today.Month.ToString("D2");
|
||||
string day = "01";
|
||||
|
||||
string sql = "SELECT FROM_UNIXTIME( FLOOR( UNIX_TIMESTAMP( d.created_time ) / 3600 ) * 3600 ) AS time_period, COUNT(*) AS count FROM " +
|
||||
$"pro_workorder AS r RIGHT JOIN pro_reportwork_detail_{year}{month}{day} AS d ON r.workorder = d.workorder " +
|
||||
"WHERE r.workorder_date = CURDATE() AND r.group_code= @groupCode " +
|
||||
" GROUP BY FLOOR( UNIX_TIMESTAMP( d.created_time ) / 600 ) ORDER BY time_period";
|
||||
|
||||
|
||||
|
||||
DataTable result = Context.Ado.GetDataTable(sql, new { groupCode = groupCode, });
|
||||
int sum = 0;
|
||||
|
||||
|
||||
foreach (DataRow row in result.Rows)
|
||||
{
|
||||
// DateTime value =(DateTime)row["time_period"];
|
||||
DateTime value = row["time_period"] != DBNull.Value ? Convert.ToDateTime(row["time_period"]) : DateTime.MinValue;
|
||||
int count = Convert.ToInt32(row["count"]);
|
||||
|
||||
// sum = sum + count;
|
||||
EchartsSeriesData echartsSeriesData = new EchartsSeriesData()
|
||||
{
|
||||
Name = value.ToString("HH:mm"),
|
||||
Value = count
|
||||
};
|
||||
echartsSeriesDatas.Add(echartsSeriesData);
|
||||
}
|
||||
int currentNum = Array.IndexOf(XAxis.Data.ToArray(), echartsSeriesDatas.Select(it => it.Name).LastOrDefault());
|
||||
for (int i = 0; i < currentNum; i++)
|
||||
{
|
||||
int point = 0;
|
||||
foreach (var item in echartsSeriesDatas)
|
||||
{
|
||||
|
||||
if (item.Name == XAxis.Data[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
point++;
|
||||
|
||||
}
|
||||
|
||||
if (point == echartsSeriesDatas.Count())
|
||||
{
|
||||
// 获取前一个时间段产量
|
||||
decimal productNum = 0;
|
||||
if (i >= 1)
|
||||
{
|
||||
productNum = echartsSeriesDatas.Where(it => it.Name == XAxis.Data[i - 1]).Select(it => it.Value).FirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
productNum = 0;
|
||||
}
|
||||
|
||||
|
||||
echartsSeriesDatas.Add(new EchartsSeriesData() { Name = XAxis.Data[i], Value = productNum });
|
||||
}
|
||||
}
|
||||
echartsSeries.Data = echartsSeriesDatas.OrderBy(it => it.Name).ToList();
|
||||
echartsOptions.Series.Add(echartsSeries);
|
||||
|
||||
//3 系列值-这组 今日计划累计完成数(每60分钟)
|
||||
//获取今天这个组的所有工单
|
||||
List<ProWorkorder> ProWorkorderList = Context.Queryable<ProWorkorder>().Where(it => it.GroupCode == groupCode && it.WorkorderDate == DateTime.Today).ToList();
|
||||
|
||||
//求出总产量需要多少s
|
||||
int allSecends = 0;
|
||||
foreach (var item in ProWorkorderList)
|
||||
{
|
||||
int num = (item.DeliveryNum ?? 0) * (item.Beat ?? 0);
|
||||
allSecends = num + allSecends;
|
||||
}
|
||||
|
||||
// 将节拍转为每60分钟产量
|
||||
int allproduct = ProWorkorderList.Sum(it => it.DeliveryNum ?? 0);
|
||||
int productOfeachTenMin = allproduct / (allSecends / (60 * 60));
|
||||
|
||||
EchartsSeries echartsSeries02 = new EchartsSeries();
|
||||
echartsSeries02.Name = groupCode + "组今日计划累计完成数(每60分钟)";
|
||||
echartsSeries02.Type = "bar";
|
||||
List<EchartsSeriesData> echartsSeriesData02s = new List<EchartsSeriesData>();
|
||||
//int all_plan_product = 0;
|
||||
for (int i = 0; i < dateTimeArray.Length; i++)
|
||||
{
|
||||
|
||||
EchartsSeriesData echartsSeriesData = new EchartsSeriesData();
|
||||
echartsSeriesData.Name = dateTimeArray[i].ToString("HH:mm");
|
||||
echartsSeriesData.Value = productOfeachTenMin;
|
||||
echartsSeriesData02s.Add(echartsSeriesData);
|
||||
//all_plan_product = all_plan_product + productOfeachTenMin;
|
||||
}
|
||||
echartsSeries02.Data = echartsSeriesData02s;
|
||||
echartsOptions.Series.Add(echartsSeries02);
|
||||
|
||||
return echartsOptions;
|
||||
|
||||
}
|
||||
}
|
||||
@ -74,7 +74,7 @@ namespace MDM.Controllers.Session
|
||||
public IActionResult MiddleStationApply(string OperationCode, string ProcessCode)
|
||||
{
|
||||
|
||||
Dictionary<string, List<Object>> result = _ISessionManagerService.MiddleProcessFlowDistribution(OperationCode, ProcessCode);
|
||||
List<string> result = _ISessionManagerService.MiddleProcessFlowDistribution(OperationCode, ProcessCode);
|
||||
return SUCCESS(result);
|
||||
}
|
||||
|
||||
@ -90,6 +90,9 @@ namespace MDM.Controllers.Session
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//TODO 完工申请
|
||||
/// <summary>
|
||||
/// 完工申请
|
||||
|
||||
@ -169,6 +169,16 @@ namespace MDM.Models.Flow
|
||||
/// 未知状态,,禁止出站
|
||||
/// </summary>
|
||||
UnknownStatus = -10,
|
||||
/// <summary>
|
||||
/// 扫码流程未完成,禁止出站
|
||||
/// </summary>
|
||||
|
||||
ScanFlowNotCompleted = -11,
|
||||
|
||||
/// <summary>
|
||||
/// 参数采集未完成,禁止出站
|
||||
/// </summary>
|
||||
ParmetersCollectNotCompleted = -12
|
||||
|
||||
}
|
||||
|
||||
|
||||
151
MDM/Models/Product/ProductProcessParameters.cs
Normal file
151
MDM/Models/Product/ProductProcessParameters.cs
Normal file
@ -0,0 +1,151 @@
|
||||
using MathNet.Numerics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MDM.Models.Session
|
||||
{
|
||||
/// <summary>
|
||||
/// 生产过程参数
|
||||
/// </summary>
|
||||
[SugarTable("product_process_parameters")]
|
||||
public class ProductProcessParameters
|
||||
{
|
||||
/// <summary>
|
||||
/// 主键
|
||||
/// </summary>
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工单号
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "workorder", Length = 50)]
|
||||
public string Workorder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 产品SN
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "product_SN", Length = 50)]
|
||||
public string ProductSN { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工艺路线编码
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "routingCode", Length = 50)]
|
||||
public string RoutingCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工序号
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "operationCode", Length = 50)]
|
||||
public string OperationCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 流程code
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "flowCode", Length = 50)]
|
||||
public string FlowCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 产线code
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "productlinebodyCode", Length = 50)]
|
||||
public string ProductlinebodyCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工站code
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "workstationCode", Length = 50)]
|
||||
public string WorkstationCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 参数名称,如:温度、压力、时间
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "parameter_code")]
|
||||
public string ParameterCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 显示名称(用于UI展示,可和name一样)
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "parameter_name", Length = 100)]
|
||||
public string ParameterName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// plc点位
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "plc_point", Length = 50)]
|
||||
public string PlcPoint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 参数描述,如:模具温度,用于热压工序
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "description", ColumnDataType = "text")]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据类型:FLOAT, INT, STRING, BOOL, AI(模拟量输入)等
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "data_type", Length = 50, IsNullable = false)]
|
||||
public string DataType { get; set; } = "FLOAT";
|
||||
|
||||
/// <summary>
|
||||
/// 单位,如:℃、MPa、秒、mm
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "unit", Length = 20)]
|
||||
public string Unit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标准/目标值(如目标温度 200.0 ℃)
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "standard_value" )]
|
||||
public decimal? StandardValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最小允许值(用于报警/校验)
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "min_value")]
|
||||
public decimal? MinValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大允许值(用于报警/校验)
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "max_value")]
|
||||
public decimal? MaxValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最小允许值(用于报警/校验)
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "result")]
|
||||
public int? Result { get; set; }
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 创建人
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "createdby", Length = 50)]
|
||||
public string Createdby { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新人
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "updatedby", Length = 50)]
|
||||
public string Updatedby { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "created_time")]
|
||||
public DateTime? CreatedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "updated_time")]
|
||||
public DateTime? UpdatedTime { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
99
MDM/Models/Product/ProductScanRecord.cs
Normal file
99
MDM/Models/Product/ProductScanRecord.cs
Normal file
@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MDM.Models.Session
|
||||
{
|
||||
[SugarTable("product_scan_records")]
|
||||
public class ProductScanRecords
|
||||
{
|
||||
/// <summary>
|
||||
/// 主键ID
|
||||
/// </summary>
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = false)]
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工单号
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "workorder", Length = 50)]
|
||||
public string Workorder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 过程码
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "product_SN", Length = 50)]
|
||||
public string ProductSN { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工艺路线code
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "routingcode", Length = 50)]
|
||||
public string Routingcode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工序code
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "operationCode", Length = 50)]
|
||||
public string OperationCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 流程code
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "flowCode", Length = 50)]
|
||||
public string FlowCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 实际扫到码
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "actual_scan_code", Length = 100)]
|
||||
public string ActualScanCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 期望扫到的码
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "expected_code", Length = 100)]
|
||||
public string ExpectedCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 防错规则
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "error_proof_rule_code", Length = 50)]
|
||||
public string ErrorProofRuleCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扫码结果(OK,NG)
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "scan_result")]
|
||||
public ScanResultEnum? ScanResult { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 错误码代号
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "error_code", Length = 50)]
|
||||
public string ErrorCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 错误信息
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "error_message", Length = 255)]
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扫码时间
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "scan_time")]
|
||||
public DateTime? ScanTime { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 扫码结果枚举
|
||||
/// </summary>
|
||||
public enum ScanResultEnum
|
||||
{
|
||||
OK = 1,
|
||||
NG = 0
|
||||
}
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MDM.Models.Session
|
||||
{
|
||||
|
||||
}
|
||||
@ -1,54 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MDM.Models.Session
|
||||
{
|
||||
[SugarTable("product_scan_record")]
|
||||
public class ProductScanRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// 主键ID
|
||||
/// </summary>
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = false)] // bigint类型,非自增
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 实际扫到码
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "actual_scan_code", Length = 100)]
|
||||
public string ActualScanCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 期望扫到的码
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "expected_code", Length = 100)]
|
||||
public string ExpectedCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扫码结果 (建议:0-失败,1-成功)
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "scan_result")]
|
||||
public int? ScanResult { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 错误码代号
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "error_code", Length = 50)]
|
||||
public string ErrorCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 错误信息
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "error_message", Length = 255)]
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扫码时间
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "scan_time")]
|
||||
public DateTime? ScanTime { get; set; }
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
|
||||
using DOAN.Model.MES.product;
|
||||
using DOAN.Model.MES.recipe;
|
||||
using DOAN.Model.MES.recipe.Dto;
|
||||
using Infrastructure.Attribute;
|
||||
@ -10,6 +11,7 @@ using MDM.Models.Process;
|
||||
using MDM.Models.Session;
|
||||
using MDM.Service;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using System.Text.Json;
|
||||
|
||||
|
||||
namespace MDM.Services.Flows
|
||||
@ -190,19 +192,13 @@ namespace MDM.Services.Flows
|
||||
//TODO: 下发中间操作流程规则
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//TODO: 扫码流程 类型
|
||||
[RIZOFlow(FlowType = "Scanningcode_flow")]
|
||||
public List<ProcessOperationFlowMaterialParamter> ScanningcodeFlow(string RoutingCode, string operationCode, string FlowCode)
|
||||
public string ScanningcodeFlow(string RoutingCode, string operationCode, string FlowCode)
|
||||
{
|
||||
|
||||
|
||||
//获取这个工序d的扫码规则
|
||||
List<ProcessOperationFlowMaterialParamter> ScanningFlowList = Context.Queryable<ProcessOperationFlow>().LeftJoin<ProcessOperationFlowMaterialParamter>((f, m) => f.FkRoutingCode == m.FkRoutingCode && f.FkOperationCode == m.FkOperationCode && f.FlowCode == m.FkFlowCode)
|
||||
|
||||
.Where((f, m) => f.FkRoutingCode == RoutingCode && f.FkOperationCode == operationCode && f.FlowTypeCode == "Scanningcode_flow"&&f.FlowCode== FlowCode)
|
||||
List<ProcessOperationFlowMaterialParamter> flowRuleList = Context.Queryable<ProcessOperationFlow>().LeftJoin<ProcessOperationFlowMaterialParamter>((f, m) => f.FkRoutingCode == m.FkRoutingCode && f.FkOperationCode == m.FkOperationCode && f.FlowCode == m.FkFlowCode)
|
||||
.Where((f, m) => f.FkRoutingCode == RoutingCode && f.FkOperationCode == operationCode && f.FlowTypeCode == "Scanningcode_flow" && f.FlowCode == FlowCode)
|
||||
.Select((f, m) => new ProcessOperationFlowMaterialParamter()
|
||||
{
|
||||
id = f.id,
|
||||
@ -212,24 +208,35 @@ namespace MDM.Services.Flows
|
||||
MaterialCode = m.MaterialCode,
|
||||
MaterialName = m.MaterialName,
|
||||
UseErrorProofRuleCode = m.UseErrorProofRuleCode,
|
||||
|
||||
|
||||
})
|
||||
.ToList();
|
||||
return ScanningFlowList;
|
||||
var data = new
|
||||
{
|
||||
flowbase = new
|
||||
{
|
||||
routingCode = RoutingCode,
|
||||
operationCode = operationCode,
|
||||
flowCode = FlowCode
|
||||
},
|
||||
flowRuleList
|
||||
|
||||
};
|
||||
return System.Text.Json.JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true });
|
||||
|
||||
}
|
||||
|
||||
//TODO: 数采流程 类型 (工位流程)
|
||||
[RIZOFlow(FlowType = "data_collect_flow")]
|
||||
public List<ProcessOperationWorkstationFlowCollectParameter> DataCollectFlow( string RoutingCode, string operationCode, string FlowCode, string ProductlinebodyCode, string WorkstationCode)
|
||||
public string DataCollectFlow(string RoutingCode, string operationCode, string FlowCode, string ProductlinebodyCode, string WorkstationCode)
|
||||
{
|
||||
//获取这个工序d的扫码规则
|
||||
List<ProcessOperationWorkstationFlowCollectParameter> DataCollectFlowList = Context.Queryable<ProcessOperationFlow>().LeftJoin<ProcessOperationWorkstationFlowCollectParameter>
|
||||
List<ProcessOperationWorkstationFlowCollectParameter> flowRuleList = Context.Queryable<ProcessOperationFlow>().LeftJoin<ProcessOperationWorkstationFlowCollectParameter>
|
||||
((f, m) => f.FkRoutingCode == m.FkRoutingCode && f.FkOperationCode == m.FkOperationCode && f.FlowCode == m.FkFlowCode)
|
||||
.Where((f, m) => f.FkRoutingCode == RoutingCode && f.FkOperationCode == operationCode && f.FlowTypeCode == "Scanningcode_flow")
|
||||
.Where((f,m)=>m.FkProductlinebodyCode== ProductlinebodyCode&&m.FkWorkstationCode== WorkstationCode&&m.FkFlowCode==FlowCode)
|
||||
.Where((f, m) => m.FkProductlinebodyCode == ProductlinebodyCode && m.FkWorkstationCode == WorkstationCode && m.FkFlowCode == FlowCode)
|
||||
.Select((f, m) => new ProcessOperationWorkstationFlowCollectParameter()
|
||||
{
|
||||
{
|
||||
FkRoutingCode = f.FkRoutingCode,
|
||||
FkOperationCode = f.FkOperationCode,
|
||||
FkProductlinebodyCode = m.FkProductlinebodyCode,
|
||||
@ -250,23 +257,34 @@ namespace MDM.Services.Flows
|
||||
DefaultValue = m.DefaultValue,
|
||||
IsRequired = m.IsRequired,
|
||||
Sequence = m.Sequence,
|
||||
|
||||
|
||||
|
||||
})
|
||||
.ToList();
|
||||
return DataCollectFlowList;
|
||||
var data = new
|
||||
{
|
||||
flowbase = new
|
||||
{
|
||||
routingCode = RoutingCode,
|
||||
operationCode = operationCode,
|
||||
productlinebodyCode = ProductlinebodyCode,
|
||||
workstationCode = WorkstationCode,
|
||||
flowCode = FlowCode
|
||||
},
|
||||
flowRuleList
|
||||
|
||||
};
|
||||
return System.Text.Json.JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true });
|
||||
|
||||
|
||||
}
|
||||
|
||||
//TODO: 配方流程 类型
|
||||
[RIZOFlow(FlowType = "recipe_distribute_flow")]
|
||||
public List<PfRecipeParametersDto> RecipeDistributeFlow(string RoutingCode, string operationCode, string FlowCode)
|
||||
public string RecipeDistributeFlow(string RoutingCode, string operationCode, string FlowCode)
|
||||
{
|
||||
return Context.Queryable<PfRefProductRecipe>()
|
||||
var flowRuleList = Context.Queryable<PfRefProductRecipe>()
|
||||
.LeftJoin<PfRecipeVersion>((refpr, ver) => refpr.RecipeCode == ver.RecipeCode)
|
||||
.LeftJoin<PfRecipeParameters>((refpr, ver, param) => ver.RecipeCode == param.RecipeCode && ver.Version == param.Version)
|
||||
.Where((refpr, ver, param) => refpr.FkFlowCode== FlowCode&&refpr.FkRoutingCode == RoutingCode && refpr.FkOperationCode == operationCode)
|
||||
.Where((refpr, ver, param) => refpr.FkFlowCode == FlowCode && refpr.FkRoutingCode == RoutingCode && refpr.FkOperationCode == operationCode)
|
||||
.Select((refpr, ver, param) => new PfRecipeParametersDto
|
||||
{
|
||||
Id = param.Id,
|
||||
@ -279,7 +297,18 @@ namespace MDM.Services.Flows
|
||||
StandardValue = param.StandardValue,
|
||||
Remark = param.Remark
|
||||
}).ToList();
|
||||
|
||||
var data = new
|
||||
{
|
||||
flowbase = new
|
||||
{
|
||||
routingCode = RoutingCode,
|
||||
operationCode = operationCode,
|
||||
flowCode = FlowCode
|
||||
},
|
||||
flowRuleList
|
||||
|
||||
};
|
||||
return System.Text.Json.JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true });
|
||||
|
||||
}
|
||||
|
||||
@ -289,69 +318,112 @@ namespace MDM.Services.Flows
|
||||
/// <param name="operationCode"></param>
|
||||
/// <param name="processCode"></param>
|
||||
/// <returns></returns>
|
||||
//[RIZOFlow(FlowType = "common_outbound_flow")]
|
||||
//public OutStationApplyResult CommonOutboundStationFlow(string operationCode, string processCode)
|
||||
//{
|
||||
// // 参数验证
|
||||
// if (string.IsNullOrWhiteSpace(operationCode) || string.IsNullOrWhiteSpace(processCode))
|
||||
// {
|
||||
// return OutStationApplyResult.InvalidParameters;
|
||||
// }
|
||||
// // 获取产品是正常件,完成件,返工件
|
||||
// var product = GetProductBySn(processCode);
|
||||
// if (product == null)
|
||||
// {
|
||||
// // 产品未开工,不得出站
|
||||
// return OutStationApplyResult.ProductNotStartWork;
|
||||
// }
|
||||
// if (product.ProductStatus == 2)
|
||||
// {
|
||||
// // 产品已经生产完成,不得出站
|
||||
// return OutStationApplyResult.ProductCompleted;
|
||||
// }
|
||||
// //如果正常件
|
||||
// if (product.ProductStatus == 2)
|
||||
// {
|
||||
// // 此工序未入站,禁止出站
|
||||
[RIZOFlow(FlowType = "common_outbound_flow")]
|
||||
public OutStationApplyResult CommonOutboundStationFlow(string operationCode, string processCode)
|
||||
{
|
||||
// 参数验证
|
||||
if (string.IsNullOrWhiteSpace(operationCode) || string.IsNullOrWhiteSpace(processCode))
|
||||
{
|
||||
return OutStationApplyResult.InvalidParameters;
|
||||
}
|
||||
|
||||
// // 此工序未完成中间流程,禁止出站
|
||||
// 1.获取产品是正常件,完成件,返工件
|
||||
ProductLifecycle productInfo = Context.Queryable<ProductLifecycle>()
|
||||
.Where(p => p.ProductSN == processCode)
|
||||
.First();
|
||||
if (productInfo == null)
|
||||
{
|
||||
// 产品未开工,不得出站
|
||||
RecordOutTrace(productInfo, operationCode, 1, ApplyStatusEnum.REJECTED, OutStationApplyResult.ProductNotStartWork.ToString(), "产品未开工,不得入站");
|
||||
return OutStationApplyResult.ProductNotStartWork;
|
||||
}
|
||||
if (productInfo.ProductStatus == 2)
|
||||
{
|
||||
// 产品已经生产完成,不得出站
|
||||
RecordOutTrace(productInfo, operationCode, 1, ApplyStatusEnum.REJECTED, OutStationApplyResult.ProductCompleted.ToString(), "产品已经生产完成,不得入站");
|
||||
return OutStationApplyResult.ProductCompleted;
|
||||
}
|
||||
if (productInfo.ProductStatus == 3)
|
||||
{
|
||||
// 返工件允许出站
|
||||
RecordOutTrace(productInfo, operationCode, 1, ApplyStatusEnum.SUCCESS, OutStationApplyResult.Success.ToString(), string.Empty);
|
||||
return OutStationApplyResult.Success;
|
||||
}
|
||||
|
||||
//检查扫码流程是否已经完成
|
||||
var ScanResults = Context.Queryable<ProcessOperationFlowMaterialParamter>()
|
||||
.LeftJoin<ProductScanRecords>((f, r) => f.FkFlowCode == r.FlowCode && f.FkRoutingCode == r.Routingcode && f.FkOperationCode == r.OperationCode)
|
||||
.Where((f, r) => f.FkRoutingCode == productInfo.RoutingCode)
|
||||
.Where((f, r) => f.FkOperationCode == operationCode)
|
||||
.Select((f, r) => new { f.FkFlowCode, r.ScanResult })
|
||||
.ToList();
|
||||
|
||||
// //插入出站记录
|
||||
// ProductPassstationRecord passstationRecord = new ProductPassstationRecord
|
||||
// {
|
||||
// Workorder = product.Workorder,
|
||||
// Routingcode = product.RoutingCode,
|
||||
// ProductSN = product.ProductSN,
|
||||
// OperationCode = operationCode,
|
||||
// ProuductStatus = 3, // 出站状态
|
||||
// OutStationTime = DateTime.Now,
|
||||
// CreatedTime = DateTime.Now
|
||||
// };
|
||||
// Context.Insertable(passstationRecord).ExecuteCommand();
|
||||
// return OutStationApplyResult.Success;
|
||||
// }
|
||||
// //如果,返工件
|
||||
// if (product.ProductStatus == 3)
|
||||
// {
|
||||
// //插入出站记录
|
||||
// ProductPassstationRecord passstationRecord = new ProductPassstationRecord
|
||||
// {
|
||||
// Workorder = product.Workorder,
|
||||
// Routingcode = product.RoutingCode,
|
||||
// ProductSN = product.ProductSN,
|
||||
// OperationCode = operationCode,
|
||||
// ProuductStatus = 4, // 出站状态
|
||||
// OutStationTime = DateTime.Now,
|
||||
// CreatedTime = DateTime.Now
|
||||
// };
|
||||
// Context.Insertable(passstationRecord).ExecuteCommand();
|
||||
// return OutStationApplyResult.Success;
|
||||
// }
|
||||
bool isFinish= ScanResults.Where(it => it.ScanResult == ScanResultEnum.NG||it.ScanResult==null).Any();
|
||||
|
||||
if (isFinish)
|
||||
{
|
||||
RecordOutTrace(productInfo, operationCode, 1, ApplyStatusEnum.REJECTED, OutStationApplyResult.ScanFlowNotCompleted.ToString(), "产品未开工,不得入站");
|
||||
return OutStationApplyResult.ScanFlowNotCompleted;
|
||||
}
|
||||
|
||||
//检查数采流程是否已经完成
|
||||
// 获取产线
|
||||
string LineCode = Context.Queryable<ProWorkorder>().Where(it => it.Workorder == productInfo.Workorder).Select(it=>it.LineCode).First();
|
||||
|
||||
var DataCollectList = Context.Queryable<ProcessOperationWorkstationFlowCollectParameter>()
|
||||
.LeftJoin<ProductProcessParameters>((f, p) => f.FkFlowCode == p.FlowCode && f.FkRoutingCode == p.RoutingCode && f.FkOperationCode == p.OperationCode && f.ParameterCode == p.ParameterCode)
|
||||
.Where((f, p) => f.FkRoutingCode == productInfo.RoutingCode&&f.FkOperationCode== operationCode&&f.FkProductlinebodyCode==LineCode)
|
||||
.Select((f, r) => new { f.FkFlowCode, r.Result })
|
||||
.ToList();
|
||||
|
||||
bool isFinish_ = DataCollectList.Where(it => it.Result == 0 || it.Result == null).Any();
|
||||
if (isFinish_)
|
||||
{
|
||||
RecordOutTrace(productInfo, operationCode, 1, ApplyStatusEnum.REJECTED, OutStationApplyResult.ParmetersCollectNotCompleted.ToString(), "产品未开工,不得入站");
|
||||
return OutStationApplyResult.ParmetersCollectNotCompleted;
|
||||
}
|
||||
//准许出站
|
||||
return OutStationApplyResult.Success;
|
||||
}
|
||||
|
||||
private void RecordOutTrace(ProductLifecycle product, string operationCode, int ProductionLifeStage, ApplyStatusEnum isPass, string rejectReasonCode, string rejectReasonDesc)
|
||||
{
|
||||
// 更新产品状态
|
||||
if (product != null)
|
||||
{
|
||||
Context.Updateable<ProductLifecycle>()
|
||||
.SetColumns(it => new ProductLifecycle
|
||||
{
|
||||
ProductStatus = 1, // 设置为生产中状态
|
||||
UpdatedTime = DateTime.Now
|
||||
})
|
||||
.Where(it => it.ProductSN == product.ProductSN)
|
||||
.ExecuteCommand();
|
||||
}
|
||||
|
||||
// 构建入站记录
|
||||
var passstationRecord = new ProductPassstationRecord
|
||||
{
|
||||
Workorder = product?.Workorder,
|
||||
Routingcode = product?.RoutingCode,
|
||||
ProductSN = product?.ProductSN ?? string.Empty,
|
||||
OperationCode = operationCode,
|
||||
ProductionLifeStage = ProductionLifeStage, // 生产中
|
||||
ApplyType = ApplyTypeEnum.OUT,
|
||||
ApplyStatus = isPass,
|
||||
RejectReasonCode = rejectReasonCode,
|
||||
RejectReasonDesc = rejectReasonDesc,
|
||||
InStationTime = DateTime.Now,
|
||||
CreatedTime = DateTime.Now
|
||||
};
|
||||
|
||||
Context.Insertable(passstationRecord).ExecuteCommand();
|
||||
|
||||
|
||||
|
||||
// return OutStationApplyResult.UnknownStatus;
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ namespace MDM.Services.Session.IService
|
||||
|
||||
InStationApplyResult InStationApply(string OperationCode, string ProcessCode);
|
||||
|
||||
Dictionary<string, List<object>> MiddleProcessFlowDistribution(string operationCode, string ProcessCode);
|
||||
List<string> MiddleProcessFlowDistribution(string operationCode, string ProcessCode);
|
||||
OutStationApplyResult OutStationApply(string OperationCode, string ProcessCode);
|
||||
|
||||
|
||||
|
||||
@ -135,19 +135,19 @@ namespace MDM.Services.Session
|
||||
/// <param name="operationCode"></param>
|
||||
/// <param name="processCode"></param>
|
||||
/// <returns></returns>
|
||||
public Dictionary<string, List<object>> MiddleProcessFlowDistribution(string operationCode, string ProcessCode)
|
||||
public List<string> MiddleProcessFlowDistribution(string operationCode, string ProcessCode)
|
||||
{
|
||||
var lifecycle = Context.Queryable<ProductLifecycle>()
|
||||
.Where(it => it.ProductSN == ProcessCode)
|
||||
.First();
|
||||
ProWorkorder proWorkorder= Context.Queryable<ProWorkorder>().Where(it=>it.Workorder== lifecycle.Workorder).First();
|
||||
ProcessOperationWorkstationMapping processOperationWorkstationMapping= Context.Queryable<ProcessOperationWorkstationMapping>().Where(it => it.FkRoutingCode == lifecycle.RoutingCode && it.FkOperationCode == operationCode && it.FkProductlinebodyCode == proWorkorder.LineCode).First();
|
||||
ProWorkorder proWorkorder = Context.Queryable<ProWorkorder>().Where(it => it.Workorder == lifecycle.Workorder).First();
|
||||
ProcessOperationWorkstationMapping processOperationWorkstationMapping = Context.Queryable<ProcessOperationWorkstationMapping>().Where(it => it.FkRoutingCode == lifecycle.RoutingCode && it.FkOperationCode == operationCode && it.FkProductlinebodyCode == proWorkorder.LineCode).First();
|
||||
|
||||
Dictionary<string, List<object>> keyValuePairs= new Dictionary<string, List<object>>();
|
||||
List<string> resultList = new List<string>();
|
||||
//TODO 获取这个工序的中间操作流程
|
||||
List<ProcessOperationFlow> operationFlows= Context.Queryable<ProcessOperationFlow>().Where(it => !it.FlowTypeCode.Contains("bound_flow")).ToList();
|
||||
List<ProcessOperationFlow> operationFlows = Context.Queryable<ProcessOperationFlow>().Where(it => !it.FlowTypeCode.Contains("bound_flow")).ToList();
|
||||
|
||||
if(operationFlows!=null&& operationFlows.Count()>0)
|
||||
if (operationFlows != null && operationFlows.Count() > 0)
|
||||
{
|
||||
// 已知程序集和类名
|
||||
string assemblyName = "MDM.Services.Flows";
|
||||
@ -174,46 +174,46 @@ namespace MDM.Services.Session
|
||||
// 获取方法的参数信息
|
||||
var parameters = method.GetParameters();
|
||||
//工序流程
|
||||
if(parameters.Length==3)
|
||||
if (parameters.Length == 3)
|
||||
{
|
||||
var result = method.Invoke(instance, new object[] { lifecycle.RoutingCode, operationCode, rizoFlow.FlowCode });
|
||||
if(result is List<object> list)
|
||||
if (result is string list)
|
||||
{
|
||||
keyValuePairs.Add(rizoFlow.FlowCode, list);
|
||||
resultList.Add(list);
|
||||
}
|
||||
}
|
||||
// 工位流程
|
||||
if (parameters.Length == 5)
|
||||
{
|
||||
var result = method.Invoke(instance, new object[] { lifecycle.RoutingCode, operationCode, rizoFlow.FlowCode, processOperationWorkstationMapping.FkProductlinebodyCode, processOperationWorkstationMapping.FkWorkstationCode });
|
||||
if (result is List<object> list)
|
||||
if (result is string list)
|
||||
{
|
||||
keyValuePairs.Add(rizoFlow.FlowCode, list);
|
||||
resultList.Add(list);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return keyValuePairs;
|
||||
return resultList;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 出站申请
|
||||
/// </summary>
|
||||
/// <param name="OperationCode"></param>
|
||||
/// <param name="ProcessCode"></param>
|
||||
/// <returns></returns>
|
||||
/// <summary>
|
||||
/// 出站申请
|
||||
/// </summary>
|
||||
/// <param name="OperationCode"></param>
|
||||
/// <param name="ProcessCode"></param>
|
||||
/// <returns></returns>
|
||||
public OutStationApplyResult OutStationApply(string OperationCode, string ProcessCode)
|
||||
{
|
||||
|
||||
@ -293,6 +293,10 @@ namespace MDM.Services.Session
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return Context.Updateable<ProductLifecycle>()
|
||||
.SetColumns(it => new ProductLifecycle()
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user