mqtt超时

This commit is contained in:
gcw_MV9p2JJN 2026-01-22 11:07:21 +08:00
parent dc37fe2496
commit 7ae1cefc11
20 changed files with 844 additions and 230 deletions

View File

@ -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);
}
}

View File

@ -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("导出失败,日期不能为空"));
}

View File

@ -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;

View File

@ -44,7 +44,7 @@ namespace DOAN.WebApi.Controllers.Mobile.product
{
var response = printAndReportWorkService.CheckBoxInspectionLabel(workorder, box_label);
return SUCCESS(response);
return SUCCESS(true);
}
//TODO 校验首标签

View File

@ -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 = 3PgSql = 4
@ -47,6 +47,13 @@
"DbType": 4, // MySql = 0, SqlServer = 1, Oracle = 3PgSql = 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 = 3PgSql = 4
"ConfigId": "5", //
"IsAutoCloseConnection": true
}
//...
],

View 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; }
}
}

View File

@ -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);
}
}

View File

@ -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) 将该时间戳除以60010分钟的秒数然后向下取整到最接近的整数。
//*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;
}
}

View File

@ -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>
/// 完工申请

View File

@ -169,6 +169,16 @@ namespace MDM.Models.Flow
/// 未知状态,,禁止出站
/// </summary>
UnknownStatus = -10,
/// <summary>
/// 扫码流程未完成,禁止出站
/// </summary>
ScanFlowNotCompleted = -11,
/// <summary>
/// 参数采集未完成,禁止出站
/// </summary>
ParmetersCollectNotCompleted = -12
}

View 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; }
}
}

View 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>
/// 扫码结果(OKNG)
/// </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
}
}

View File

@ -1,10 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MDM.Models.Session
{
}

View File

@ -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; }
}
}

View File

@ -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;
//}
}
}
}

View File

@ -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);

View File

@ -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()
{