using COSXML.Network;
|
using Furion.ClayObject.Extensions;
|
using Furion.DatabaseAccessor;
|
using Furion.DependencyInjection;
|
using Furion.DynamicApiController;
|
using Furion.FriendlyException;
|
using iWare.Wms.Application.Mapper;
|
using iWare.Wms.Application.Service.AccessInterface.Dto;
|
using iWare.Wms.Core;
|
using iWare.Wms.Core.Enum;
|
using Mapster;
|
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http.Extensions;
|
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
using Microsoft.EntityFrameworkCore;
|
using Microsoft.Extensions.Logging;
|
using Newtonsoft.Json;
|
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
|
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
|
using StackExchange.Redis;
|
using System;
|
using System.Collections.Generic;
|
using System.Diagnostics;
|
using System.Linq;
|
using System.Net;
|
using System.Runtime.InteropServices;
|
using System.Text;
|
using System.Threading.Tasks;
|
using System.Xml.Linq;
|
using static Aliyun.OSS.Model.SelectObjectRequestModel.InputFormatModel;
|
|
namespace iWare.Wms.Application
|
{
|
/// <summary>
|
/// 外部访问接口
|
/// </summary>
|
[ApiDescriptionSettings("外部访问接口", Name = "AccessInterface", Order = 100)]
|
[Route("api/[Controller]")]
|
public class AccessInterfaceService : IAccessInterfaceService, IDynamicApiController, ITransient
|
{
|
private readonly IRepository<QualityDataInfo, MasterDbContextLocator> _qualityDataInfoRep;
|
private readonly IRepository<QualityDataInfoLog, MasterDbContextLocator> _qualityDataInfoLogRep;
|
private readonly IRepository<WorkPieceInfo, MasterDbContextLocator> _workPieceInfoRep;
|
private readonly IRepository<ThreadStatusMonitor, MasterDbContextLocator> _threadStatusMonitorRep;
|
private readonly IRepository<DataCaptureConfig, MasterDbContextLocator> _dataCaptureConfigRep;
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
private readonly IRepository<WorkPieceProcess, MasterDbContextLocator> _workPieceProcessRep;
|
private readonly IAccessInterfaceLogService _accessInterfaceLog;
|
private readonly IRepository<WorkPieceInfoLog, MasterDbContextLocator> _WorkPieceInfoLog;
|
private readonly IRepository<EquipmentCurrentMonitor, MasterDbContextLocator> _equipmentCurrentMonitorRep;
|
private readonly IRepository<EquipmentBaseInfo, MasterDbContextLocator> _equipmentBaseInfoRep;
|
private readonly ISysDictTypeService _dict;
|
private readonly IRepository<ProductionPlanInfo, MasterDbContextLocator> _productionPlanInfoRep;
|
private readonly IRepository<ShiftInfo, MasterDbContextLocator> _shiftInfoRep;
|
|
/// <summary>
|
/// 外部访问构造函数
|
/// </summary>
|
/// <param name="qualityDataInfoRep"></param>
|
/// <param name="qualityDataInfoLogRep"></param>
|
/// <param name="workPieceInfoRep"></param>
|
/// <param name="httpContextAccessor"></param>
|
/// <param name="accessInterfaceLog"></param>
|
public AccessInterfaceService(IRepository<QualityDataInfo, MasterDbContextLocator> qualityDataInfoRep,
|
IRepository<QualityDataInfoLog, MasterDbContextLocator> qualityDataInfoLogRep,
|
IRepository<WorkPieceInfo, MasterDbContextLocator> workPieceInfoRep,
|
IHttpContextAccessor httpContextAccessor,
|
IAccessInterfaceLogService accessInterfaceLog,
|
IRepository<ThreadStatusMonitor, MasterDbContextLocator> threadStatusMonitorRep,
|
IRepository<DataCaptureConfig, MasterDbContextLocator> dataCaptureConfigRep,
|
IRepository<WorkPieceProcess, MasterDbContextLocator> workPieceProcessRep, WorkPieceInfoService WorkPieceInfoService,
|
IRepository<WorkPieceInfoLog, MasterDbContextLocator> workPieceInfoLog,
|
IRepository<EquipmentCurrentMonitor, MasterDbContextLocator> equipmentCurrentMonitorRep,
|
IRepository<EquipmentBaseInfo, MasterDbContextLocator> equipmentBaseInfoRep, ISysDictTypeService dict
|
, IRepository<ProductionPlanInfo, MasterDbContextLocator> productionPlanInfoRep
|
, IRepository<ShiftInfo, MasterDbContextLocator> shiftInfoRep)
|
{
|
_qualityDataInfoRep = qualityDataInfoRep;
|
_qualityDataInfoLogRep = qualityDataInfoLogRep;
|
_workPieceInfoRep = workPieceInfoRep;
|
_httpContextAccessor = httpContextAccessor;
|
_accessInterfaceLog = accessInterfaceLog;
|
_threadStatusMonitorRep = threadStatusMonitorRep;
|
_dataCaptureConfigRep = dataCaptureConfigRep;
|
_workPieceProcessRep = workPieceProcessRep;
|
_WorkPieceInfoLog = workPieceInfoLog;
|
_equipmentCurrentMonitorRep = equipmentCurrentMonitorRep;
|
_equipmentBaseInfoRep = equipmentBaseInfoRep;
|
_dict = dict;
|
_productionPlanInfoRep = productionPlanInfoRep;
|
_shiftInfoRep = shiftInfoRep;
|
}
|
public Dictionary<string, string> GetQualityDataInfoUpdate()
|
{
|
Dictionary<string, string> dict = new Dictionary<string, string>();
|
|
dict.Add("QualityState", "QualityState");
|
dict.Add("QualityStateUpdateMode", "QualityStateUpdateMode");
|
dict.Add("QualityStateUpdateUser", "QualityStateUpdateUser");
|
dict.Add("OfflineTime", "OfflineTime");
|
//dict.Add("QualityOP10To1", "QualityOP10To1");
|
//dict.Add("QualityOP10To2", "QualityOP10To2");
|
//dict.Add("QualityOP10To3", "QualityOP10To3");
|
//dict.Add("QualityOP10To4", "QualityOP10To4");
|
return dict;
|
}
|
#region M128柔性测量单元用的接口
|
/// <summary>
|
/// M31反馈质量数据
|
/// </summary>
|
/// <param name="json"></param>
|
/// <returns></returns>
|
[HttpPost("UploadQualityData")]
|
public async Task UploadQualityData([FromQuery] JsonInput input2)
|
{
|
AddAccessInterfaceLogInput addLog = new();
|
var json = input2.json;
|
addLog.Id = Yitter.IdGenerator.YitIdHelper.NextId();
|
addLog.JsonString = json;
|
addLog.Action = 2;
|
addLog.OperateAddress = $"{_httpContextAccessor.HttpContext.Request.Path}";
|
DateTime now = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local);
|
var ipAddress = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress;
|
if (ipAddress.IsIPv4MappedToIPv6)
|
{
|
addLog.IpAddress = ipAddress.MapToIPv4().ToString();
|
}
|
try
|
{
|
var input = JsonConvert.DeserializeObject<AddQualityDataInfoInputV2>(json);
|
addLog.Key = input.WorkPieceID;
|
|
if (input == null || string.IsNullOrEmpty(input.WorkPieceID) || input.QualityState == 0)
|
{
|
addLog.Result = "传入参数异常:工件号不能为空!质量结果不能没有值";
|
//await _accessInterfaceLog.AddInterfaceLogAsync(addLog);
|
throw Oops.Oh(addLog.Result);
|
}
|
var info = await _workPieceInfoRep
|
.FirstOrDefaultAsync(w => w.WorkPieceID == input.WorkPieceID.Trim());
|
if (info == null)
|
{
|
addLog.Result = $"传入参数异常:工件号{input.WorkPieceID}不能找到指定工件!";
|
//await _accessInterfaceLog.AddInterfaceLogAsync(addLog);
|
throw Oops.Oh(addLog.Result);
|
}
|
|
|
//var qualityData = _qualityDataInfoRep.Where(o => o.WorkPieceID == input.WorkPieceID).FirstOrDefault();
|
//if (qualityData == null || qualityData.WorkPieceID.Length < 1 || qualityData.WorkingProcedure.Length < 1)
|
//{//插入QualityDataInfo表
|
// qualityData = EntityPropHelper.Mapper<QualityDataInfo, WorkPieceInfo>(info);
|
// qualityData.WorkingProcedure = input.WorkingProcedure;
|
// qualityData.QualityState = input.QualityState;
|
// qualityData.Id = Yitter.IdGenerator.YitIdHelper.NextId();
|
// await _qualityDataInfoRep.InsertAsync(qualityData);
|
//}
|
////修改QualityDataInfo表(主要是质量字段) //重复收到质量信息,会覆盖之前的
|
//EntityPropHelper<QualityDataInfo, AddQualityDataInfoInput>.CopyProp(input, qualityData, GetQualityDataInfoUpdate());//指定修改字段
|
|
//qualityData.QualityReceiveTime = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local);
|
|
//QualityDataInfoLog qualitylog = EntityPropHelper.Mapper<QualityDataInfoLog, QualityDataInfo>(qualityData);
|
//qualitylog.Id = Yitter.IdGenerator.YitIdHelper.NextId();
|
//qualitylog.QualityDataInfoID = qualityData.Id;
|
//await _qualityDataInfoLogRep.InsertAsync(qualitylog);
|
|
DateTime spcStartTime;
|
DateTime spcEndTime;
|
//更新工序追溯表SPC
|
var pro = _workPieceProcessRep.Where(o => o.WorkPieceID == input.WorkPieceID && o.WorkingProcedureCurrent == input.WorkingProcedure && o.OperationType == OperationType.SPC.ToString()).FirstOrDefault();
|
if (pro == null || pro.WorkPieceID.Length < 1)
|
{
|
WorkPieceProcess process = new WorkPieceProcess();
|
process = EntityPropHelper.Mapper<WorkPieceProcess, WorkPieceInfo>(info);
|
process.StartTime = now;
|
process.EndTime = now;
|
process.Id = Yitter.IdGenerator.YitIdHelper.NextId();
|
process.CreatedUserName = "API";
|
process.CreatedTime = now;
|
process.UpdatedUserName = "API";
|
process.UpdatedTime = now;
|
process.OperationType = OperationType.SPC.ToString();
|
process.QualityState = input.QualityState;
|
process.Remarks = "柔性测量单元反馈新增";
|
process.QualityDataInfoID = addLog.Id;
|
process.WorkingProcedureCurrent = input.WorkingProcedure;
|
process.EquipmentID = "";
|
spcStartTime = process.StartTime;
|
spcEndTime = process.EndTime;
|
_workPieceProcessRep.InsertNow(process);
|
}
|
else
|
{
|
pro.QualityDataInfoID = addLog.Id;
|
pro.EndTime = now;
|
pro.UpdatedUserName = "API";
|
pro.UpdatedTime = now;
|
pro.QualityState = input.QualityState;
|
spcStartTime = pro.StartTime;
|
spcEndTime = pro.EndTime;
|
}
|
|
|
info.QualityState = input.QualityState;
|
if (!info.QualityState.Equals(((int)EnumQualityState.OK).ToString()))
|
{
|
info.QualityErrorInfo = $"SPC不合格";
|
}
|
else
|
{
|
info.QualityErrorInfo = "";
|
}
|
if (input.QualityState != (int)EnumQualityState.OK)
|
{
|
//更新表WorkPieceInfo
|
info.WorkPieceState = (int)WorkPieceState.WIP;//推出后和SPC抽检后 质量录入时状态修改回在制品
|
info.UpdatedUserName = "api";
|
info.QualityStateUpdateUser = input.QualityStateUpdateUser;
|
info.QualityStateUpdateTime = now;
|
info.QualityStateUpdateMode = EnumQualityStateUpdateMode.SPC.ToString();
|
info.Remarks = $"SPC不合格,质量状态变更";
|
info.UpdatedTime = now;
|
info.CompleteTime = null;
|
|
WorkPieceInfoLog infolog = EntityPropHelper.Mapper<WorkPieceInfoLog, WorkPieceInfo>(info);
|
infolog.Id = Yitter.IdGenerator.YitIdHelper.NextId();
|
infolog.WorkPieceInfoID = info.Id;
|
infolog.LogAddTime = DateTime.Now;
|
infolog.LogAddRemark = $"【{CurrentUserInfo.Name}】 柔性测量单元反馈质量信息";
|
_WorkPieceInfoLog.InsertAsync(infolog);
|
|
//当某到工序检测到不合格工件时,从该工件加工完成时刻前指定时间起至报检不合格时间止,系统将该工件的最后加工工序在该时间段内加工的所有工件、正在加工的工件、该工序入口处的第一个工件全部标记为疑似状态,由人工复检工件并修改状态,并支持批量变更。
|
//答复:在线测量不需要走这个流程,只有SPC抽检才需要,需要把这时间段的工件全部置为疑似,哪怕是已完成工件
|
//时间段起始时间:抽检工件生产时间前一SPC抽检时间
|
//时间段结束时间:抽检工件质量结果出现后的时间
|
//抽检工件工序扫描枪外入口处的第一个工件 也把质量状态置为疑似
|
//(每一工序SPC抽检是设置的固定的,比如200抽4,状态置为疑似时若工件还在设备内,会继续生产完毕后排出)
|
|
DateTime NOOKStartTime;
|
DateTime NOOKEndTime;
|
if (input.CompletedTimeHand.HasValue && input.CompletedTimeHand > now.AddHours(-1))
|
{
|
NOOKEndTime = input.CompletedTimeHand.Value;
|
}
|
else
|
{
|
addLog.Result = $"M31质量上传工件测量完成时间{input.CompletedTime}异常!";
|
throw Oops.Oh(addLog.Result);
|
}
|
//CompletedTime SPC质量完成时间
|
//获取抽检工件生产时间前一SPC抽检时间
|
var previousSPC = _workPieceProcessRep.Where(o => o.WorkingProcedureCurrent == input.WorkingProcedure
|
&& o.OperationType == OperationType.SPC.ToString() && o.StartTime < spcStartTime
|
).OrderByDescending(o => o.StartTime).FirstOrDefault();
|
if (previousSPC != null && previousSPC.StartTime > now.AddDays(-1))
|
{//避免上一工件抽检时间过长 (24小时)
|
NOOKStartTime = previousSPC.StartTime;
|
}
|
else
|
{//没有找到上一抽检工件 或上一抽检工件超过24小时,则就用当前工件SPC开始时间
|
NOOKStartTime = spcStartTime;
|
}
|
|
var updatelist = _workPieceProcessRep.Where(o => o.WorkingProcedureCurrent == input.WorkingProcedure
|
&& o.OperationType == OperationType.生产.ToString() && o.StartTime < NOOKEndTime && o.StartTime > NOOKStartTime);
|
foreach (var update in updatelist)
|
{
|
var updateinfo = await _workPieceInfoRep
|
.FirstOrDefaultAsync(w => w.WorkPieceID == update.WorkPieceID);
|
if (updateinfo == null)
|
{
|
addLog.Result = $"传入参数异常:工件号{input.WorkPieceID}不能找到指定工件!";
|
continue;
|
}
|
updateinfo.WorkPieceState = (int)WorkPieceState.WIP;//推出后和SPC抽检后 质量录入时状态修改回在制品
|
updateinfo.QualityState = (int)EnumQualityState.Suspected;
|
updateinfo.QualityErrorInfo = $"工件{update.WorkPieceID}在工序{input.WorkingProcedure}抽检不合格,相关工件质量状态变更为疑似";;
|
updateinfo.QualityStateUpdateUser = input.QualityStateUpdateUser;
|
updateinfo.QualityStateUpdateTime = now;
|
updateinfo.QualityStateUpdateMode = EnumQualityStateUpdateMode.SPC.ToString();
|
updateinfo.Remarks = $"工件{update.WorkPieceID}在工序{input.WorkingProcedure}抽检不合格,相关工件质量状态变更为疑似";
|
updateinfo.CompleteTime = null;
|
}
|
|
}
|
addLog.Result = $"工件号{input.WorkPieceID} M31质量上传成功!";
|
//await _accessInterfaceLog.AddInterfaceLogAsync(addLog);
|
|
}
|
catch (Exception ex)
|
{
|
//addLog.Result = $"M31质量上传失败!";
|
throw Oops.Oh(addLog.Result + ex.Message);
|
}
|
finally
|
{
|
try
|
{
|
|
await _accessInterfaceLog.AddInterfaceLogAsync(addLog);
|
}
|
catch (Exception ex32)
|
{
|
addLog.Result = $"M31质量上传失败1!";
|
throw Oops.Oh(addLog.Result);
|
}
|
}
|
|
|
}
|
|
/// <summary>
|
/// 分页查询数据收集工序配置
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpGet("GetWorkingProcedureForID")]
|
public async Task<AccessWorPieceInfoOutput> GetWorkingProcedureForID([FromQuery] AccessWorkPieceInfoInput input)
|
{
|
AddAccessInterfaceLogInput addLog = new();
|
addLog.JsonString = JsonConvert.SerializeObject(input);
|
addLog.Action = 2;
|
addLog.Key = input.WorkPieceID;
|
addLog.OperateAddress = $"{_httpContextAccessor.HttpContext.Request.Path}";
|
var ipAddress = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress;
|
if (ipAddress.IsIPv4MappedToIPv6)
|
{
|
addLog.IpAddress = ipAddress.MapToIPv4().ToString();
|
}
|
|
if (input == null || string.IsNullOrEmpty(input.WorkPieceID))
|
{
|
addLog.Result = "传入参数异常:工件号不能为空!";
|
await _accessInterfaceLog.AddInterfaceLogAsync(addLog);
|
throw Oops.Oh(addLog.Result);
|
}
|
|
var workPieceInfo = await _workPieceInfoRep.DetachedEntities
|
.FirstOrDefaultAsync(w => w.WorkPieceID == input.WorkPieceID.Trim());
|
if (workPieceInfo == null)
|
{
|
addLog.Result = $"传入参数异常:工件号{input.WorkPieceID}不能找到指定工件!";
|
await _accessInterfaceLog.AddInterfaceLogAsync(addLog);
|
throw Oops.Oh(addLog.Result);
|
}
|
var re = workPieceInfo.Adapt<AccessWorPieceInfoOutput>();
|
|
addLog.Result = re;
|
|
await _accessInterfaceLog.AddInterfaceLogAsync(addLog);
|
|
return re;
|
}
|
|
#endregion
|
|
#region 大屏接口
|
/// <summary>
|
/// 获取设备实时状态
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpGet("GetEquipmentCurrentState")]
|
[AllowAnonymous]
|
public async Task<List<EquipmentCurrentMonitorOutputV2>> GetEquipmentLst([FromQuery] EquipmentCurrentMonitorSearch input)
|
{
|
|
var equipmentCurrentMonitors = await (from monitor in _equipmentCurrentMonitorRep.DetachedEntities
|
join baseinfo in _equipmentBaseInfoRep.DetachedEntities
|
on monitor.EquipmentID equals baseinfo.EquipmentId into joinedEmpty
|
from baseinfo2 in joinedEmpty.DefaultIfEmpty()
|
where monitor.EquipmentID != "HMI"
|
select new EquipmentCurrentMonitorOutputV2
|
{
|
Id = monitor.Id,
|
EquipmentID = monitor.EquipmentID,
|
EquipmentName = baseinfo2.EquipmentName,
|
EquipmentCurrentStateHand = monitor.EquipmentCurrentState,
|
//EquipmentCurrentStateName = monitor.Value,
|
WorkingProcedure = monitor.WorkingProcedure,
|
AlertTime = monitor.AlertTime,
|
FailureType = monitor.FailureType,
|
Alertmsg = monitor.Alertmsg,
|
Remarks = monitor.Remarks,
|
WarnType = monitor.WarnType,
|
Warnmsg = monitor.Warnmsg,
|
WarnTime = monitor.WarnTime
|
})
|
.ProjectToType<EquipmentCurrentMonitorOutputV2>()
|
.OrderBy(o => o.EquipmentID)
|
.ToListAsync();
|
|
return equipmentCurrentMonitors;
|
}
|
|
/// <summary>
|
/// 获取当前年份所在的12个月生产完成情况
|
/// </summary>
|
[HttpGet("GetProduceCompletionStatus")]
|
[AllowAnonymous]
|
public async Task<List<ProduceCompletionStatus>> GetProduceCompletionStatus()
|
{
|
List<ProduceCompletionStatus> list = new List<ProduceCompletionStatus>();
|
|
//获取当前年的第一天
|
var yearOneDay= DateTime.Now.AddDays(-((int)DateTime.Now.DayOfYear - 1)).Date;
|
//获取月份计划
|
var productionPlanInfos = _productionPlanInfoRep.DetachedEntities
|
.Where(o=>o.IsDeleted==false&& o.PlanType.Equals("2")).ToList();
|
try
|
{
|
//获取最近一年下线工件的成品
|
var Completionlist = _workPieceInfoRep.DetachedEntities
|
.Where(o => o.IsDeleted == false && o.WorkPieceLastOfflineTime >= yearOneDay
|
&& o.WorkPieceLastOfflineTime < yearOneDay.AddYears(1)
|
&& o.WorkPieceState == (int)WorkPieceState.FinishedProducts).ProjectToType<WorkPieceInfoOutput>().ToList()
|
.GroupBy(o => o.WorkPieceLastOfflineTimeHand)
|
.Select(o => new { YearMonth = o.Key, CompletionNum = o.Count() }).ToList();
|
for (int i = 1; i <= 12; i++)
|
{
|
//当前月份
|
var month = yearOneDay.Date.AddMonths((i - 1)).ToString("yyyy-MM");
|
var plan = productionPlanInfos.Where(o => o.PlanTime.ToString("yyyy-MM") == month).FirstOrDefault();
|
ProduceCompletionStatus produceCompletionStatus = new ProduceCompletionStatus();
|
produceCompletionStatus.Month = i.ToString();
|
produceCompletionStatus.PlanCompletionNum = (plan == null ? 0 : plan.PlanProductionNum);
|
|
var completion = Completionlist.Where(o => o.YearMonth.Equals(month)).FirstOrDefault();
|
produceCompletionStatus.CompletionNum = (completion == null ? 0 : completion.CompletionNum);
|
if (produceCompletionStatus.PlanCompletionNum == 0)
|
{
|
produceCompletionStatus.PlanCompletionRate = 0;
|
|
}
|
else
|
{
|
produceCompletionStatus.PlanCompletionRate = Math.Round(((double)produceCompletionStatus.CompletionNum / (double)produceCompletionStatus.PlanCompletionNum), 3) * 100;
|
}
|
list.Add(produceCompletionStatus);
|
|
}
|
|
}
|
catch(Exception ex)
|
{
|
|
}
|
return list;
|
|
}
|
/// <summary>
|
/// 获取当前班次/月份的 实际产量和计划产量
|
/// </summary>
|
[HttpGet("GetCurrentProduceInfo")]
|
[AllowAnonymous]
|
public async Task<CurrentProduceInfo> GetCurrentProduceInfo()
|
{
|
CurrentProduceInfo currentProduceInfo = new CurrentProduceInfo();
|
//获取当前月
|
var month = DateTime.Now.ToString("yyyy-MM");
|
//获取当前天
|
var day = DateTime.Now.ToString("yyyy-MM-dd");
|
//获取当前月份计划
|
var productionPlanInfos = _productionPlanInfoRep.DetachedEntities.ProjectToType<ProductionPlanInfoOutput>().ToList()
|
.Where(o => o.PlanType.Equals("2")&& o.PlanTimeHand.Equals(month)).FirstOrDefault();
|
//获取最近月下线工件的成品
|
try
|
{
|
|
var MonthCompletionnNum = _workPieceInfoRep.DetachedEntities.ProjectToType<WorkPieceInfoOutput>().ToList()
|
.Where(o => o.WorkPieceLastOfflineTimeHand.Equals(month)
|
&& o.WorkPieceState == (int)WorkPieceState.FinishedProducts).Count();
|
currentProduceInfo.CurrentMonthProduceNum = MonthCompletionnNum;
|
}
|
catch(Exception ex)
|
{
|
|
}
|
//获取最近月下线工件的成品
|
var DayCompletionnNum = _workPieceInfoRep.DetachedEntities.ProjectToType<WorkPieceInfoOutput>().ToList()
|
.Where(o => o.WorkPieceLastOfflineTimeDayHand.Equals(day)
|
&& o.WorkPieceState == (int)WorkPieceState.FinishedProducts).Count();
|
|
//获取班次班组信息
|
var shiftlist = _shiftInfoRep.DetachedEntities.ProjectToType<ShiftInfoOutput>().ToList().Where(o=>o.StartTime<DateTime.Now&&o.EndTime> DateTime.Now).FirstOrDefault();
|
|
currentProduceInfo.CurrentShiftProduceNum = DayCompletionnNum;
|
currentProduceInfo.CurrentShiftPlanNum = 0;
|
currentProduceInfo.CurrentMonthPlanNum = (productionPlanInfos==null?0: productionPlanInfos.PlanProductionNum);
|
|
if(shiftlist==null)
|
{
|
currentProduceInfo.CurrentTime = DateTime.Now;
|
currentProduceInfo.CurrentTeamLeader = "袁班长";
|
currentProduceInfo.CurrentTeamName = "白班";
|
}
|
else
|
{
|
//获取班次计划
|
var shiftplan = _productionPlanInfoRep.DetachedEntities.ProjectToType<ProductionPlanInfoOutput>().ToList()
|
.Where(o => o.PlanType.Equals("1")&&o.TeamType.Equals(shiftlist.ShiftName)&& o.PlanTimeDayHand.Equals(day)).FirstOrDefault();
|
currentProduceInfo.CurrentTime = DateTime.Now;
|
currentProduceInfo.CurrentTeamLeader = shiftlist.ShiftRemark;
|
currentProduceInfo.CurrentTeamName = shiftlist.ShiftName;
|
if(shiftplan!=null)
|
{
|
currentProduceInfo.CurrentShiftPlanNum = shiftplan.PlanProductionNum;
|
}
|
}
|
try
|
{
|
DateTime time = DateTime.Now;
|
var dicts = await _dict.GetDictTreeOutput();
|
var dict = dicts.Where(o => o.Code.Equals("last_failure_time"));//获取最新故障时间,用了判断安全生产多少天用
|
if (dict.Any())
|
{
|
if (DateTime.TryParse(dict.FirstOrDefault().Remark, out time))
|
{
|
currentProduceInfo.CurrentSafeProductionDay = ((int)((DateTime.Now - time).TotalDays)).ToString();
|
}
|
else
|
{
|
currentProduceInfo.CurrentSafeProductionDay = "";
|
}
|
}
|
else
|
{
|
currentProduceInfo.CurrentSafeProductionDay = "";
|
}
|
|
}
|
catch(Exception ex)
|
{
|
currentProduceInfo.CurrentSafeProductionDay = "异常";
|
}
|
return currentProduceInfo;
|
}
|
/// <summary>
|
/// 获取大屏质量数据显示
|
/// </summary>
|
/// <param name="input">传返回参数的QualityType</param>
|
/// <returns></returns>
|
[HttpGet("GetQualityData")]
|
[AllowAnonymous]
|
public async Task<QualityDataDisplay> GetQualityData([FromQuery] string input)
|
{
|
QualityDataDisplay qualityDataDisplay = new QualityDataDisplay();
|
|
List<string> list = new List<string>();
|
list.Add("OP10连杆厚度");
|
//list.Add("OP20小头孔直径");
|
//list.Add("OP20大头孔直径");
|
list.Add("OP30涨断力矩");
|
list.Add("OP35压装力矩");
|
//list.Add("OP40大头孔直径");
|
//list.Add("OP60大头孔直径");
|
Random rd = new Random((int)DateTime.Now.Ticks);
|
var str = list[rd.Next(0, list.Count - 1)];
|
switch (str)
|
{
|
case "OP10连杆厚度":
|
qualityDataDisplay.QualityType = str;
|
var datas = _qualityDataInfoRep.DetachedEntities.ProjectToType<QualityDataInfoOutput>()
|
.Where(o=>!string.IsNullOrEmpty(o.QualityOP10To1)&& !string.IsNullOrEmpty(o.WorkPieceID))
|
.OrderByDescending(o => o.OP10QualityReceiveTime)
|
.Select(o=>new QualityData() { WorkPieceID = o.WorkPieceID, QualityDataVaule = double.Parse( o.QualityOP10To1) })
|
.Take(10).Reverse().ToList();
|
qualityDataDisplay.list = datas;
|
break;
|
case "OP30涨断力矩":
|
qualityDataDisplay.QualityType = str;
|
var dataop30ch1 = _qualityDataInfoRep.DetachedEntities.ProjectToType<QualityDataInfoOutput>()
|
.Where(o => !string.IsNullOrEmpty(o.QualityOP30To1)&&!string.IsNullOrEmpty(o.WorkPieceID))
|
.OrderByDescending(o => o.OP30QualityReceiveTimeCH3)
|
.Select(o => new QualityData() { WorkPieceID = o.WorkPieceID, QualityDataVaule = double.Parse(o.QualityOP30To1.Replace("kN", "")) })
|
.Take(10).Reverse().ToList();
|
qualityDataDisplay.list = dataop30ch1;
|
break;
|
case "OP35压装力矩":
|
qualityDataDisplay.QualityType = str;
|
var dataop35 = _qualityDataInfoRep.DetachedEntities.ProjectToType<QualityDataInfoOutput>()
|
.Where(o => !string.IsNullOrEmpty(o.QualityOP35To1)&&!string.IsNullOrEmpty(o.WorkPieceID))
|
.OrderByDescending(o => o.OP35QualityReceiveTime)
|
.Select(o => new QualityData() { WorkPieceID = o.WorkPieceID, QualityDataVaule = double.Parse(o.QualityOP35To1) })
|
.Take(10).Reverse().ToList();
|
qualityDataDisplay.list = dataop35;
|
break;
|
default:
|
break;
|
}
|
return qualityDataDisplay;
|
|
}
|
|
/// <summary>
|
/// 获取大屏的刷新频率(微妙)
|
/// </summary>
|
[HttpGet("GetLargeScreenFrequency")]
|
[AllowAnonymous]
|
public async Task<int> GetLargeScreenFrequency()
|
{
|
try
|
{
|
|
var dicts = await _dict.GetDictTreeOutput();
|
var dict = dicts.Where(o => o.Code.Equals("screen_refresh_frequency"));
|
if (dict.Any())
|
{
|
int num = int.Parse(dict.FirstOrDefault().Remark);
|
if (num < 1000 || num > 100000)
|
{
|
return 5000;
|
}
|
else
|
{
|
return num;
|
}
|
}
|
else
|
{
|
return 5000;
|
}
|
}
|
catch(Exception ex)
|
{
|
|
return 6000;
|
}
|
|
|
}
|
/// <summary>
|
/// 获取指定时间范围内的产量信息
|
/// </summary>
|
/// <param name="start"></param>
|
/// <param name="end"></param>
|
/// <returns></returns>
|
[HttpGet("GetProductionForTime")]
|
[AllowAnonymous]
|
public async Task<List<ProductionInfo>> GetProductionForTime(DateTime start,DateTime end)
|
{
|
//获取最近月下线工件的成品
|
var Production = from info in _workPieceInfoRep.DetachedEntities.ProjectToType<WorkPieceInfoOutput>().ToList()
|
where info.WorkPieceLastOfflineTime>=start
|
where info.WorkPieceLastOfflineTime<=end
|
where info.WorkPieceState==(int)WorkPieceState.FinishedProducts
|
group info by info.WorkPieceLastOfflineTimeDayHand into grouplist
|
select new ProductionInfo()
|
{
|
Day=grouplist.Key,
|
ProductionNum=grouplist.Count(),
|
};
|
return Production.OrderBy(o=>o.Day).ToList();
|
|
}
|
#endregion
|
|
#region 其他
|
|
/// <summary>
|
/// 添加设备质量数据
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpPost("Add")]
|
[AllowAnonymous]
|
public async Task AddQualityDataAsync(AddQualityDataInfoInput input)
|
{
|
|
var quatilyData = input.Adapt<QualityDataInfo>();
|
|
var workInfo = await _workPieceInfoRep.DetachedEntities.FirstOrDefaultAsync(w => w.WorkPieceID == input.WorkPieceID);
|
WorkPieceInfo newWorkInfo = new();
|
if (workInfo != null)
|
{
|
workInfo.EquipmentID = input.EquipmentID;
|
workInfo.WorkPieceState = 1;
|
workInfo.WorkingProcedureCurrent = input.WorkingProcedure;
|
|
await _workPieceInfoRep.UpdateAsync(workInfo);
|
}
|
else
|
{
|
quatilyData.QualityState = 3;
|
newWorkInfo.Id = Yitter.IdGenerator.YitIdHelper.NextId();
|
newWorkInfo.WorkPieceID = "GJ" + DateTime.Now.ToString("yyMMdd-HHmmssfff");
|
newWorkInfo.EquipmentID = input.EquipmentID;
|
newWorkInfo.WorkPieceState = 1;
|
newWorkInfo.WorkingProcedureCurrent = input.WorkingProcedure;
|
|
await _workPieceInfoRep.InsertAsync(newWorkInfo);
|
}
|
var quantilyDataInfo = await _qualityDataInfoRep.DetachedEntities.FirstOrDefaultAsync(q => q.WorkPieceID == input.WorkPieceID && q.WorkingProcedure == input.WorkingProcedure);
|
if (quantilyDataInfo == null)
|
{
|
var quailtyDataLog = quatilyData.Adapt<QualityDataInfoLog>();
|
quatilyData.Id = Yitter.IdGenerator.YitIdHelper.NextId();
|
quailtyDataLog.QualityDataInfoID = quatilyData.Id;
|
|
using (var tran = await _qualityDataInfoRep.Database.BeginTransactionAsync())//事务
|
{
|
try
|
{
|
await _qualityDataInfoRep.InsertAsync(quatilyData); // 质量数据
|
await _qualityDataInfoLogRep.InsertAsync(quailtyDataLog); // 质量日志
|
await tran.CommitAsync();
|
}
|
catch (Exception ex)
|
{
|
await tran.RollbackAsync();
|
throw Oops.Oh("执行失败:" + ex.Message);
|
}
|
}
|
await _qualityDataInfoRep.InsertAsync(quatilyData);
|
await _qualityDataInfoLogRep.InsertAsync(quailtyDataLog);
|
}
|
else
|
{
|
quantilyDataInfo.EquipmentID = input.EquipmentID;
|
quantilyDataInfo.QualityState = input.QualityState;
|
quantilyDataInfo.QualityStateUpdateMode = input.QualityStateUpdateMode;
|
quantilyDataInfo.QualityStateUpdateUser = input.QualityStateUpdateUser;
|
quantilyDataInfo.QualityReceiveTime = input.QualityReceiveTime;
|
quantilyDataInfo.OfflineTime = input.OfflineTime;
|
switch (input.EquipmentID)
|
{
|
case "EOP10":
|
quantilyDataInfo.QualityOP10To1 = input.QualityOP10To1;
|
break;
|
case "EOP20":
|
quantilyDataInfo.QualityOP20To1 = input.QualityOP20To1;
|
break;
|
case "EOP30":
|
quantilyDataInfo.QualityOP30To1 = input.QualityOP30To1;
|
quantilyDataInfo.QualityOP30To2 = input.QualityOP30To2;
|
quantilyDataInfo.QualityOP30To3 = input.QualityOP30To3;
|
quantilyDataInfo.QualityOP30To4 = input.QualityOP30To4;
|
quantilyDataInfo.QualityOP30To5 = input.QualityOP30To5;
|
quantilyDataInfo.QualityOP30To6 = input.QualityOP30To6;
|
quantilyDataInfo.QualityOP30To7 = input.QualityOP30To7;
|
quantilyDataInfo.QualityOP30To8 = input.QualityOP30To8;
|
quantilyDataInfo.QualityOP30To9 = input.QualityOP30To9;
|
quantilyDataInfo.QualityOP30To10 = input.QualityOP30To10;
|
quantilyDataInfo.QualityOP30To11 = input.QualityOP30To11;
|
break;
|
case "EOP35":
|
quantilyDataInfo.QualityOP35To1 = input.QualityOP35To1;
|
quantilyDataInfo.QualityOP35To2 = input.QualityOP35To2;
|
break;
|
case "EOP40":
|
quantilyDataInfo.QualityOP40To1 = input.QualityOP40To1;
|
break;
|
case "EOP60":
|
quantilyDataInfo.QualityOP60To1 = input.QualityOP60To1;
|
quantilyDataInfo.QualityOP60To2 = input.QualityOP60To2;
|
break;
|
case "EOP70":
|
quantilyDataInfo.QualityOP70To1 = input.QualityOP70To1;
|
quantilyDataInfo.QualityOP70To2 = input.QualityOP70To2;
|
quantilyDataInfo.QualityOP70To3 = input.QualityOP70To3;
|
break;
|
case "EOP80":
|
quantilyDataInfo.QualityOP80To1 = input.QualityOP80To1;
|
quantilyDataInfo.QualityOP80To2 = input.QualityOP80To2;
|
quantilyDataInfo.QualityOP80To3 = input.QualityOP80To3;
|
quantilyDataInfo.QualityOP80To4 = input.QualityOP80To4;
|
quantilyDataInfo.QualityOP80To5 = input.QualityOP80To5;
|
quantilyDataInfo.QualityOP80To6 = input.QualityOP80To6;
|
quantilyDataInfo.QualityOP80To7 = input.QualityOP80To7;
|
quantilyDataInfo.QualityOP80To8 = input.QualityOP80To8;
|
quantilyDataInfo.QualityOP80To9 = input.QualityOP80To9;
|
quantilyDataInfo.QualityOP80To10 = input.QualityOP80To10;
|
break;
|
}
|
var quailtyDataInfoLog = quantilyDataInfo.Adapt<QualityDataInfoLog>();
|
quailtyDataInfoLog.Id = Yitter.IdGenerator.YitIdHelper.NextId();
|
quailtyDataInfoLog.QualityDataInfoID = quantilyDataInfo.Id;
|
|
await _qualityDataInfoRep.UpdateAsync(quantilyDataInfo);
|
await _qualityDataInfoLogRep.InsertAsync(quailtyDataInfoLog);
|
|
}
|
AddAccessInterfaceLogInput addLog = new();
|
addLog.JsonString = JsonConvert.SerializeObject(input);
|
addLog.Action = 1;
|
addLog.Key = input.WorkingProcedure;
|
addLog.IpAddress = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString();
|
addLog.OperateAddress = $"{_httpContextAccessor.HttpContext.Request.Path}{_httpContextAccessor.HttpContext.Request.QueryString}";// _httpContextAccessor.HttpContext.Request.GetEncodedUrl();
|
await _accessInterfaceLog.AddInterfaceLogAsync(addLog);
|
}
|
|
/// <summary>
|
/// 获取工件信息
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpGet("workPieceInfo")]
|
[AllowAnonymous]
|
public async Task<AccessWorPieceInfoOutput> GetWorkPieceInfoAsync([FromQuery] AccessWorkPieceInfoInput input)
|
{
|
var workPieceInfo = await _workPieceInfoRep.DetachedEntities
|
.FirstOrDefaultAsync(w => w.WorkPieceID == input.WorkPieceID.Trim());
|
|
AddAccessInterfaceLogInput addLog = new();
|
addLog.JsonString = JsonConvert.SerializeObject(input);
|
addLog.Action = 2;
|
addLog.Key = input.WorkPieceID;
|
addLog.Result = workPieceInfo;
|
var ipAddress = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress;
|
if (ipAddress.IsIPv4MappedToIPv6)
|
{
|
addLog.IpAddress = ipAddress.MapToIPv4().ToString();
|
}
|
addLog.OperateAddress = $"{_httpContextAccessor.HttpContext.Request.Path}";// {_httpContextAccessor.HttpContext.Request.QueryString}"; //_httpContextAccessor.HttpContext.Request.GetEncodedUrl();
|
await _accessInterfaceLog.AddInterfaceLogAsync(addLog);
|
|
return workPieceInfo == null ? null : workPieceInfo.Adapt<AccessWorPieceInfoOutput>();
|
}
|
|
/// <summary>
|
/// 更新线程状态监控
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpPost("ThreadStatus")]
|
[AllowAnonymous]
|
public async Task AddThreadStatusAsync(AddThreadStatusMonitorInput input)
|
{
|
var dataCapture = await _dataCaptureConfigRep.DetachedEntities.FirstOrDefaultAsync(d => d.WorkingProcedure == input.Threadcode);
|
var threadStatusMonitor = await _threadStatusMonitorRep.DetachedEntities.FirstOrDefaultAsync(t => t.Threadcode == input.Threadcode);
|
if (threadStatusMonitor == null)
|
{
|
var threadMonitior = new ThreadStatusMonitor();
|
threadMonitior.Threadcode = input.Threadcode;
|
threadMonitior.ThreadId = input.ThreadId;
|
threadMonitior.Threadstatue = 1;
|
threadMonitior.Threadstarttime = DateTime.Now;
|
threadMonitior.Threadlastmodifytime = DateTime.Now;
|
threadMonitior.Threadcname = input.Threadcname;
|
threadMonitior.ThreadFrequency = dataCapture?.DataCaptureFrequency ?? 0;
|
|
await _threadStatusMonitorRep.InsertAsync(threadMonitior);
|
}
|
else
|
{
|
if (threadStatusMonitor.Threadstatue == 1)
|
{
|
threadStatusMonitor.Threadstatue = 2;
|
threadStatusMonitor.Threadendtime = DateTime.Now;
|
threadStatusMonitor.Threadlastmodifytime = DateTime.Now;
|
}
|
if (threadStatusMonitor.Threadstatue == 2)
|
{
|
threadStatusMonitor.Threadstatue = 1;
|
threadStatusMonitor.Threadstarttime = DateTime.Now;
|
threadStatusMonitor.Threadendtime = null;
|
threadStatusMonitor.Threadlastmodifytime = DateTime.Now;
|
|
await _threadStatusMonitorRep.UpdateAsync(threadStatusMonitor);
|
}
|
}
|
AddAccessInterfaceLogInput addLog = new();
|
addLog.JsonString = JsonConvert.SerializeObject(input);
|
addLog.Action = 1;
|
addLog.Key = input.Threadcode;
|
addLog.IpAddress = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString();
|
addLog.OperateAddress = $"{_httpContextAccessor.HttpContext.Request.Path}{_httpContextAccessor.HttpContext.Request.QueryString}";
|
await _accessInterfaceLog.AddInterfaceLogAsync(addLog);
|
}
|
#endregion
|
}
|
}
|