zhuangpei-mesbackend/DOAN.Service/JobKanban/WorkorderProgressService.cs
2025-12-27 14:01:25 +08:00

490 lines
18 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using DOAN.Infrastructure.Helper;
using DOAN.Model.JobKanban;
using DOAN.Model.MES.base_;
using DOAN.Model.MES.mm;
using DOAN.Model.MES.product;
using DOAN.Model.MES.product.Dto;
using DOAN.Model.MES.recipe;
using DOAN.Model.Mobile;
using DOAN.Service.JobKanban.IService;
using DOAN.Service.MES.mm.line;
using DOAN.Service.MES.product;
using Infrastructure.Attribute;
using Mapster;
using NPOI.SS.Formula.Functions;
using Org.BouncyCastle.Asn1;
using SqlSugar.SplitTableExtensions;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace DOAN.Service.JobKanban;
[AppService(ServiceType = typeof(IWorkorderProgressService), ServiceLifetime = LifeTime.Transient)]
public class WorkorderProgressService : BaseService<ProWorkorder>, IWorkorderProgressService
{
private ProProducttypeSpecService _proProducttypeSpecService = new ProProducttypeSpecService();
public List<BaseWorkRoute> GetRoutes()
{
return Context.Queryable<BaseWorkRoute>().Where(it => it.Status == 1).ToList();
}
public List<BaseGroup> GetGroups()
{
return Context.Queryable<BaseGroup>().Where(it => it.Status == 1).ToList();
}
public List<ProWorkorder> GetWorkOrderList(string group_code, string line_code, DateTime handleDate)
{
handleDate = handleDate.ToLocalTime().Date;
return Context.Queryable<ProWorkorder>().Where(it => it.GroupCode == group_code)
.Where(it => it.LineCode == line_code)
.Where(it => it.WorkorderDate == handleDate)
.ToList();
}
public List<ProReportwork> GetReportWorkRecord(string group_code, string line_code, DateTime handleDate)
{
return Context.Queryable<ProWorkorder>().LeftJoin<ProReportwork>((w, r) => w.Workorder == r.FkWorkorder)
.Where((w, r) => w.GroupCode == group_code)
.Where((w, r) => w.LineCode == line_code)
.Where((w, r) => w.WorkorderDate == handleDate)
.Select((w, r) => new
{
FkWorkorder = w.Workorder,
DispatchNum = w.DeliveryNum,
FinishedNum = r.FinishedNum,
})
.ToList().Adapt<List<ProReportwork>>();
}
/// <summary>
/// 获取工单列表 未完成
/// </summary>
/// <param name="today"></param>
/// <param name="LineCode"></param>
/// <returns></returns>
public List<ProWorkorderDto4> GetWorkOrderListNoFinish(DateTime today, string line_code, string group_code)
{
today = today.ToLocalTime().Date;
var query1 = Context.Queryable<ProWorkorder>()
.Where(it => it.WorkorderDate == today)
.Where(it => it.LineCode == line_code)
.Where(it => it.GroupCode == group_code)
.Where(it => it.Status == 1 || it.Status == 2)
;
var ProWorkorderDto4List = Context.Queryable(query1)
.LeftJoin<ProReportwork>((q, r) => q.Workorder == r.FkWorkorder)
.Select((q, r) => new ProWorkorderDto4
{
FinishNum = r.FinishedNum
}, true)
.MergeTable()
.OrderBy(it => it.Sort)
.ToList();
if (ProWorkorderDto4List.Count > 0)
foreach (var item in ProWorkorderDto4List)
item.progress = SearchMaterialPreparationProgress(item.Workorder);
return ProWorkorderDto4List;
}
public ProWorkorderDto4 GetWorkOrderDetail(string workorder)
{
var query = Context.Queryable<ProWorkorder>()
.Where(it => it.Workorder == workorder);
return Context.Queryable(query)
.LeftJoin<ProReportwork>((q, r) => q.Workorder == r.FkWorkorder)
.Select((q, r) => new ProWorkorderDto4
{
FinishNum = r.FinishedNum
}, true).First();
}
public KanbanInfo GetKanbanNum(DateTime today, string line_code, string group_code)
{
var kanbanInfo = new KanbanInfo();
today = today.ToLocalTime().Date;
kanbanInfo.TotalTaskNum = Context.Queryable<ProWorkorder>()
.Where(it => it.WorkorderDate == today)
.Where(it => it.LineCode == line_code)
.Where(it => it.GroupCode == group_code)
.Count();
kanbanInfo.RemainTasKNum = Context.Queryable<ProWorkorder>()
.Where(it => it.WorkorderDate == today)
.Where(it => it.LineCode == line_code)
.Where(it => it.GroupCode == group_code)
.Where(it => it.Status == 1 || it.Status == 2)
.Count();
return kanbanInfo;
}
public async Task<int> StartWorkOrder(string workorder)
{
var result = 0;
// 获取同一天 同一组 同一线 的所有工单 把状态2 设为init 1
var handleWorkorder =
Context.Queryable<ProWorkorder>().Where(it => it.Workorder == workorder).First();
UseTran2(() =>
{
Context.Updateable<ProWorkorder>().SetColumns(it => it.Status == 1)
.Where(it => it.Status == 2)
.Where(it => it.WorkorderDate == handleWorkorder.WorkorderDate)
.Where(it => it.GroupCode == handleWorkorder.GroupCode)
.Where(it => it.LineCode == handleWorkorder.LineCode)
.ExecuteCommand();
result = Context.Updateable<ProWorkorder>().SetColumns(it => it.Status == 2)
.SetColumns(it => it.StartTime == DateTime.Now)
.Where(it => it.Workorder == workorder).ExecuteCommand();
});
//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 combinedObject = new
{
WorkorderInfo = handleWorkorder,
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();
}
MqttHelper _mqttHelper = new MqttHelper("192.168.50.163", 1883);
// 连接
await _mqttHelper.ConnectAsync();
// 发送多条消息
await _mqttHelper.PublishMessageAsync("MES/Workorder/Start", jsonString);
// 断开连接
await _mqttHelper.DisconnectAsync();
return result;
}
//新增每天首检,按规格号查对应的产品类型,如果产品类型是今天首次做,就触发首检,记录发送首检记录
//暂时是每次开工都首检
private async Task QMSFirstInspection(ProWorkorder handleWorkorder)
{
try
{
if (handleWorkorder != null && !string.IsNullOrEmpty(handleWorkorder.Specification))
{
var queryType = _proProducttypeSpecService.Queryable()
.Where(it => it.Specification == handleWorkorder.Specification)
.First();
if (queryType != null && !string.IsNullOrEmpty(queryType.ProductionType))
{
//查询记录表,看今天这个产品类型是否已经首检
//构造首检信息
InspectionRecordDto inspectionRecordDto = new InspectionRecordDto();
inspectionRecordDto.assemblyModel = queryType.Specification;
inspectionRecordDto.type = queryType.ProductionType;
inspectionRecordDto.triggerTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
inspectionRecordDto.inspectionTimes = "1";
inspectionRecordDto.inspectionStatus = "未巡检";
//调用QMS接口发送首检记录
string qmsApiUrl = "https://aliwork.zitoo.com.cn/ganxiang/patrol-info"; // QMS接口地址
// 序列化DTO为JSON请求体
string requestJson = JsonConvert.SerializeObject(inspectionRecordDto);
var content = new StringContent(requestJson, Encoding.UTF8, "application/json");
HttpClient httpClient = new HttpClient();
// 发送POST请求接口通常为POST若为GET需调整
HttpResponseMessage response = await httpClient.PostAsync(qmsApiUrl, content);
string responseJson = await response.Content.ReadAsStringAsync();
QmsFirstInspectionResponseDto responseDto = JsonConvert.DeserializeObject<QmsFirstInspectionResponseDto>(responseJson);
// 解析接口响应
if (responseDto != null && responseDto.Code == "200")
{
// 首检记录发送成功,记录到本地数据库
//TODO 记录首检日志
}
else
{
}
}
}
}
catch (Exception ex)
{
throw;
}
}
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();
}
public ProWorkorder GetProductingWorkorder(string line_code, DateTime handleDate)
{
//TODO 这个日期有问题??????
if (handleDate.Kind == DateTimeKind.Utc)
handleDate = handleDate.ToLocalTime().Date;
else
handleDate = handleDate.Date;
return Context.Queryable<ProWorkorder>()
.Where(it => it.LineCode == line_code)
.Where(it => it.WorkorderDate == handleDate)
.Where(it => it.Status == 2)
//.Select(it=>it.Workorder)
.First();
}
public int AddLabelLog(string labelContext, string workOrder)
{
var log = new ProReportworkDetail();
log.Id = XueHua;
log.ProductionLabelCode = labelContext;
log.Workorder = workOrder;
// log.Status = 1;
log.CreatedTime = DateTime.Now;
log.CreatedBy = "终检台";
return Context.Insertable(log).SplitTable().ExecuteCommand();
}
public int LabelWorkOrderMatch(string LabelContext, string workOrder)
{
return Context.Updateable<ProLabelTraceLog>()
.Where(it => it.Workorder == workOrder)
.Where(it => it.LabelContext == LabelContext)
.SetColumns(it => it.Status == 1)
.ExecuteCommand();
}
/// <summary>
/// 防错并且报工
/// </summary>
/// <param name="workorder"></param>
/// <param name="labelContext"></param>
/// <returns></returns>
public int ErrorProofingAndReportingWork(string workorder, string labelContext)
{
var checked_workorder = Context.Queryable<ProWorkorder>().Where(it => it.Workorder == workorder)
.First();
//if (!labelContext.Contains(checked_workorder.Specification))
// 产品不属于这个工单里
if (labelContext.IndexOf(checked_workorder.Specification, StringComparison.OrdinalIgnoreCase) < 0)
{
return -1;
}
// 增加标签长度判断 36个字符
//if (labelContext.Length != 40)
//{
// return -2;
//}
// 记录条码
var detail = new ProReportworkDetail();
detail.Id = XueHua;
detail.Workorder = workorder;
detail.ProductionLabelCode = labelContext;
detail.CreatedBy = "MES";
detail.CreatedTime = DateTime.Now;
Context.Insertable(detail).SplitTable().ExecuteCommand();
// 累加报工数
var reportWork = new ProReportwork();
reportWork.Id = XueHua;
reportWork.FkWorkorder = workorder;
reportWork.DispatchNum = checked_workorder.DeliveryNum;
reportWork.FinishedNum = 1;
reportWork.GroupCode = checked_workorder.GroupCode;
reportWork.LineCode = checked_workorder.LineCode;
reportWork.CreatedTime = DateTime.Now;
reportWork.CreatedBy = "kanban";
reportWork.UpdatedBy = "kanban";
reportWork.UpdatedTime = DateTime.Now;
var ExistReportwork = Context.Queryable<ProReportwork>().Where(it => it.FkWorkorder == workorder).First();
var result = 0;
if (ExistReportwork != null)
{
reportWork.FinishedNum = ExistReportwork.FinishedNum + 1;
result += Context.Updateable<ProReportwork>().Where(it => it.FkWorkorder == workorder)
.SetColumns(it => new ProReportwork()
{
UpdatedBy = reportWork.UpdatedBy,
UpdatedTime = reportWork.UpdatedTime,
FinishedNum = reportWork.FinishedNum
}
)
.ExecuteCommand();
}
else
{
reportWork.FinishedNum = 1;
result += Context.Insertable(reportWork).ExecuteCommand();
}
// TODO 线边库出库(产线触摸屏)
/* try
{
// 计算Bom表
string InvCode = checked_workorder.ProductionCode;
// 查看需要的子件
var bomList = Context.Queryable<BaseMaterialBom>().Where(it => it.InvCode == InvCode).ToList();
foreach(BaseMaterialBom bom in bomList)
{
int quantity = 0;
if (int.TryParse(bom.Iusequantity, out int res))
{
quantity = res;
}
MmLineInventoryService mmLineInventoryService = new MmLineInventoryService();
mmLineInventoryService.outboundLineMaterial(2,reportWork.LineCode, bom.SubInvCode, checked_workorder.Workorder, reportWork.LineCode, quantity);
}
}
catch (Exception)
{
throw;
}*/
return result;
}
public int FinishWorkorder(string workorder, int finish_num)
{
var result = 0;
result = Context.Updateable<ProWorkorder>()
.Where(it => it.Workorder == workorder)
.SetColumns(it => it.EndTime == DateTime.Now.ToLocalTime())
.SetColumns(it => it.Status == 3)
.ExecuteCommand();
return result;
}
public (int, int) GetWorkOrderProgress(string workorder)
{
var result = Context.Queryable<ProReportwork>().Where(it => it.FkWorkorder == workorder)
.Select(it => new { it.DispatchNum, it.FinishedNum }).First();
if (result == null)
{
return (0, 0);
}
(int, int) tuple = (result.DispatchNum ?? 0, result.FinishedNum ?? 0);
return tuple;
}
public (DateTime, float) GetWorkOrderTime(string workorder)
{
var result = Context.Queryable<ProWorkorder>().Where(it => it.Workorder == workorder)
.Select(it => new { it.StartTime, it.Beat, it.DeliveryNum }).First();
(DateTime, float) tuple = (result.StartTime ?? DateTime.MinValue,
(result.Beat * result.DeliveryNum ?? 0) / 3600);
return tuple;
}
//查询工单下的扫描条码信息
public List<ProReportworkDetail> GetWorkOrderScanCodeInfo(string workorder)
{
return Context.Queryable<ProReportworkDetail>().SplitTable(tabs => tabs.Take(1)).Where(it => it.Workorder == workorder).ToList();
}
/// <summary>
/// 根据工单号 查询每个工单号进度
/// </summary>
/// <param name="Workorder"></param>
/// <returns></returns>
private MaterialPreparationProgress SearchMaterialPreparationProgress(string Workorder)
{
var progress = new MaterialPreparationProgress();
//TODO 查询工单总任务数
progress.WorkOrder = Workorder;
progress.Preparation_all_num = Context.Queryable<MmPreparationTask>()
.Where(it => it.FkWorkorder == Workorder)
.Count();
progress.Preparationed_num = Context.Queryable<MmPreparationTask>().Where(it => it.FkWorkorder == Workorder)
.Where(it => it.PreparationStatus == 2)
.Count();
if (progress.Preparationed_num == progress.Preparation_all_num)
progress.PreparationStatus = 2;
else if (progress.Preparationed_num < progress.Preparation_all_num) progress.PreparationStatus = 1;
if (progress.Preparation_all_num == 0) progress.PreparationStatus = 0;
return progress;
}
public bool SwitchWorkOrderCheckLabel(string pre_workorder)
{
var result = Context.Queryable<ProInspectionLabel>().Where(it => it.Workorder == pre_workorder)
.Select(it => it.EndLabel).First();
if (!string.IsNullOrEmpty(result))
{
return true;
}
else
{
return false;
}
}
}