You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

829 lines
28 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.ObjectModel;
using log4net;
using Aucma.Core.CodeBinding.Common;
using LiveCharts;
using Admin.Core.Model;
using Admin.Core.Service;
using LiveCharts.Wpf;
using Admin.Core.IService;
using Microsoft.Extensions.DependencyInjection;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Collections;
using Aucma.Core.CodeBinding.Models;
using System.Reflection.Emit;
using NPOI.SS.Formula.Functions;
using System.Threading;
using System.Windows.Threading;
using static Admin.Core.Service.CodeBindingRecordServices;
using System.Windows.Data;
using System.Windows;
using System.Linq;
using System.Collections.Generic;
using NPOI.HSSF.Record;
using SqlSugar;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Admin.Core.Model.ViewModels;
using System.Windows.Media;
using System.Drawing;
using Brushes = System.Windows.Media.Brushes;
using Admin.Core.Model.Model_New;
using Microsoft.IdentityModel.Logging;
using static Npgsql.Replication.PgOutput.Messages.RelationMessage;
using Aucma.Core.HwPLc;
using System.Windows.Documents;
using Admin.Core.Common;
using Aucma.Core.CodeBinding.Business;
using Aucma.Core.Scanner;
using LiveCharts.Defaults;
using Admin.Core.Socket;
using System.Runtime.ConstrainedExecution;
/*
* 首页信息
*/
namespace Aucma.Core.CodeBinding.ViewModels
{
public partial class IndexPageViewModel : ObservableObject
{
private static readonly log4net.ILog log = LogManager.GetLogger(typeof(IndexPageViewModel));
private readonly ICodeBindingRecordServices? _codeBindingRecordServices;
private readonly IBaseMaterialInfoServices? _baseMaterialInfoServices;
private readonly IBaseBomInfoServices? _baseBomInfoServices;
private readonly IPrintBarCodeServices? _printBarCodeServices;
// 过点数据表物料完成记录MaterialCompletion
private readonly IMaterialCompletionServices? _iMaterialCompletionServices;
// 静态变量存code1,mes条码
private static string code1Str = string.Empty;
// 静态变量存code2,SN条码
private static string code2Str = string.Empty;
//配置文件扫码器列表
private static List<ScannerModel> allScanners = Appsettings.app<ScannerModel>("ScannerServer").ToList();
// mes扫码器ip
private static string MesScannerIp = allScanners.First(x => x.Name == "mes扫码器").Ip;
// sn扫码器ip
private static string SnScannerIp = allScanners.First(x => x.Name == "sn扫码器").Ip;
public IndexPageViewModel()
{
try
{
_codeBindingRecordServices = App.ServiceProvider.GetService<ICodeBindingRecordServices>();
_baseBomInfoServices = App.ServiceProvider.GetService<IBaseBomInfoServices>();
_baseMaterialInfoServices = App.ServiceProvider.GetService<IBaseMaterialInfoServices>();
_printBarCodeServices = App.ServiceProvider.GetService<IPrintBarCodeServices>();
_iMaterialCompletionServices = App.ServiceProvider.GetService<IMaterialCompletionServices>();
// Business.MvCodeHelper.ReceiveCodeEvent += ReceiveCode;
// Business.MvCodeHelper.BindingCodeEvent += BindingCode;
// Business.MvCodeHelper.NoReadEvent += ReceiveNoRead;
TouchSocketService.ReceiveCodeDelegateEvent += ReceiveCode;
TouchSocketService.NoReadReceiveEvent += ReceiveNoRead;
GunBusiness.BindingReceiveCodeEvent += BindingCode;
GunBusiness.RefreshMaterialCodeStrEvent += ReceiveCode;
LoadData();
//实时绑定条码和实时下发plc放行信号
realBindingAndSendPlc();
LoadCharts();
//Task.Run(() =>
//{
// Thread.Sleep(4000);
//});
}
catch (Exception ex)
{
log.Error(ex);
}
}
/// <summary>
/// 实时绑定条码和实时下发plc放行信号
/// </summary>
public void realBindingAndSendPlc()
{
string tempCode1;
string tempCode2;
// 实时绑定条码
Task.Run(() =>
{
while (true)
{
try
{
if (!string.IsNullOrEmpty(code1Str) && !string.IsNullOrEmpty(code2Str))
{
BindingCode(code1Str, code2Str);
code1Str = string.Empty;
code2Str = string.Empty;
}
}
catch (Exception ex)
{
code1Str = string.Empty;
code2Str = string.Empty;
Console.WriteLine(ex.ToString());
}
Thread.Sleep(500);
}
});
// 心跳线程
Task.Run(() =>
{
try
{
Thread.Sleep(3000);
var obj = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("条码绑定Plc"));
if (obj != null)
{
while (true)
{
SendHeart(obj, "0");
Thread.Sleep(1000);
SendHeart(obj, "1");
Thread.Sleep(1000);
}
}
}
catch (Exception ex)
{
log.Error(ex.ToString());
}
});
#region 暂未启用
// 实时下发plc放行信号
//Task.Run(() =>
//{
// try
// {
// while (true)
// {
// Thread.Sleep(3000);
// var obj = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("条码绑定Plc"));
// if (obj != null && obj.plc.IsConnected)
// {
// CodeBindingRecord record = _codeBindingRecordServices.FirstAsync(x => x.isPlcPass == 1 && x.RecordTime2 >= System.DateTime.Now.AddDays(-1)).Result;
// if (record != null)
// {
// // 下发plc放行信号
// RefreshAndWriteLog($"条码[{record.BoxCode}]下发plc放行信号等待plc反馈...");
// if (SendPlcPass(obj))
// {
// RefreshAndWriteLog($"条码[{record.BoxCode}]放行成功");
// record.isPlcPass = 2;
// _ = _codeBindingRecordServices.UpdateAsync(record).Result;
// LoadData();
// }
// else
// {
// RefreshAndWriteLog("等待Plc反馈信号5秒超时!");
// }
// }
// }
// Thread.Sleep(1000);
// }
// }
// catch (Exception ex)
// {
// log.Error(ex.ToString());
// }
//});
#endregion
}
#region 加载DataGrid数据
private async void LoadData()
{
try
{
// LoadCharts();
List<CodeBindingRecord> records = null;
records = _codeBindingRecordServices.QueryAsync(x => x.BoxCode != null && x.RecordTime2 >= DateTime.Today && x.RecordTime2 < DateTime.Today.AddDays(1)).Result;
if (records != null && records.Count > 0)
{
records = records.OrderBy(x => x.RecordTime2).ToList();
Application.Current.Dispatcher.Invoke(() =>
{
ListItems.Clear();
foreach (CodeBindingRecord record in records)
{
ListItems.Insert(0, new ReaderInfo()
{
No = ListItems.Count + 1,
BoxCode = record.BoxCode,
ProductCode = record.ProductCode,
BoxName = record.BoxName,
BindingResult = record.BindingResult,
RecordTime = record.RecordTime2.ToString()
});
}
});
}
}
catch (Exception)
{
}
}
// 修改为统计近一天白班或夜班
private async void LoadCharts()
{
try
{
List<CodeBindCharts> list = _codeBindingRecordServices.QueryCharts().Result;
if (list == null || list.Count == 0) return;
var result = from m in list
group m by GetSubstringBetweenCommas(m.BoxName) into g
select new CodeBindCharts()
{
BoxName = g.Key,
Amount = g.Sum(m => m.Amount)
};
App.Current.Dispatcher.Invoke(() =>
{
ProductionHourList.Clear();
ModelStatistics.Clear();
// 图表赋值
ChartValues<ObservablePoint> achievement = new ChartValues<ObservablePoint>();
int i = 0;
double total = 0;
foreach (var item in result)
{
ProductionHourList.Add(item.BoxName);
achievement.Add(new ObservablePoint(i, item.Amount));
total += item.Amount;
i++;
}
//加一个汇总柱状图
ProductionHourList.Add("合计");
achievement.Add(new ObservablePoint(i, total));
var column = new ColumnSeries();
column.DataLabels = true;
column.Title = "型号";
column.Values = achievement;
column.Foreground = Brushes.White;
ModelStatistics.Add(column);
});
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// 截取两个逗号之间的字符串
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
static string GetSubstringBetweenCommas(string input)
{
if (input == null) return null;
// 找到第一个逗号的位置
int firstCommaIndex = input.IndexOf(',');
if (firstCommaIndex != -1)
{
// 找到第二个逗号的位置
int secondCommaIndex = input.IndexOf(',', firstCommaIndex + 1);
if (secondCommaIndex != -1)
{
// 使用Substring截取第一个逗号和第二个逗号之间的字符
return input.Substring(firstCommaIndex + 1, secondCommaIndex - firstCommaIndex - 1);
}
else
{
return null;
}
}
else
{
return null;
}
}
#endregion
#region 参数定义
/// <summary>
/// 条码1
/// </summary>
private string code1 = string.Empty;
public string Code1
{
get { return code1; }
set
{
code1 = value;
OnPropertyChanged(nameof(Code1));
}
}
/// <summary>
/// 条码1扫描时间
/// </summary>
private string code1Time = string.Empty;
public string Code1Time
{
get { return code1Time; }
set
{
code1Time = value;
OnPropertyChanged(nameof(Code1Time));
}
}
/// <summary>
/// 条码2
/// </summary>
private string code2 = string.Empty;
public string Code2
{
get { return code2; }
set
{
code2 = value;
OnPropertyChanged(nameof(Code2));
}
}
///// <summary>
///// 条码2扫描时间
///// </summary>
private string code2Time = string.Empty;
public string Code2Time
{
get { return code2Time; }
set
{
code2Time = value;
OnPropertyChanged(nameof(Code2Time));
}
}
/// <summary>
/// 绑定提示信息
/// </summary>
private string bindingInfo = string.Empty;
public string BindingInfo
{
get { return bindingInfo; }
set
{
bindingInfo = value;
OnPropertyChanged(nameof(BindingInfo));
}
}
#region 日产量柱状图X轴日期
/// <summary>
/// 日产量柱状图X轴日期
/// </summary>
private List<string> productionHourList = new List<string>();
public List<string> ProductionHourList
{
get { return productionHourList; }
set { productionHourList = value; }
}
#endregion
#region 型号统计柱状图
/// <summary>
/// 型号统计柱状图
/// </summary>
private SeriesCollection modelStatistics = new SeriesCollection();
public SeriesCollection ModelStatistics
{
get { return modelStatistics; }
set { modelStatistics = value; }
}
#endregion
#endregion
#region 初始化datagrid
private ObservableCollection<ReaderInfo> listItems = new ObservableCollection<ReaderInfo>() { };
public ObservableCollection<ReaderInfo> ListItems
{
get { return listItems; }
set
{
listItems = value;
OnPropertyChanged();//属性通知
}
}
#endregion
/// <summary>
/// NoRead处理
/// </summary>
/// <param name="scannerIp"></param>
private async void ReceiveNoRead(string scannerIp)
{
// ScannerModel model = allScanners.FirstOrDefault(x => x.Ip == scannerIp);
if (scannerIp == MesScannerIp)
{
// log.Info("MES条码NoRead:");
Clear();
SendPlcStop();
RefreshAndWriteLog("MES条码未扫描到,NoRead报警,线体停止,请重新扫描!");
}
else if (SnScannerIp == scannerIp)
{
Clear();
SendPlcStop();
RefreshAndWriteLog("SN条码未扫描到,NoRead报警,线体停止,请重新扫描!");
}
}
/// <summary>
/// 页面扫码信息清空
/// </summary>
public void Clear()
{
code1Str = string.Empty;
code2Str = string.Empty;
// 页面扫码信息清空
Code1 = string.Empty;
Code2 = string.Empty;
Code1Time = string.Empty;
Code2Time = string.Empty;
BindingInfo = string.Empty;
}
/// <summary>
/// 接收扫码器传输的条码扫码器ip
/// </summary>
/// <param name="code1"></param>
/// <param name="scannerIp"></param>
private void ReceiveCode(string scannerIp, string codeStr)
{
// ScannerModel model = allScanners.FirstOrDefault(x => x.Ip == scannerIp);
if (MesScannerIp == scannerIp)
{
log.Info("扫描到MES条码:" + codeStr);
// 全局变量赋值SN码扫描后使用
code1Str = codeStr;
RefreshCode1(codeStr);
}
else if (SnScannerIp == scannerIp)
{
Clear();
log.Info("扫描到成品条码:" + codeStr);
// 1.刷新界面条码信息
// 全局变量赋值,mes条码扫描后使用
code2Str = codeStr;
RefreshCode2(codeStr);
}
#region
// 2.创建任务更新数据库条码1
// CodeBindingRecord codeRecord = new CodeBindingRecord();
// codeRecord.BoxCode = code1;
// codeRecord.BoxName = "去别的数据库查询";
//List<BaseBomInfo> bomInfo = await _baseBomInfoServices.QueryAsync(x => x.MaterialCode == code);
//string aa = bomInfo.FirstOrDefault().MaterialName;
// codeRecord.RecordTime1 = time;
// int a = await _codeBindingRecordServices.AddAsync(codeRecord);
// 页面刷新ListItems
//await Application.Current.Dispatcher.InvokeAsync(() =>
//{
// // 在 UI 线程上操作列表
// ListItems.Insert(0, new ReaderInfo() { No = codeRecord.ObjId, BoxCode = codeRecord.BoxCode, RecordTime = codeRecord.RecordTime1.ToString() });
//});
//log.Info("条码1记录更新");
#endregion
}
private void RefreshCode1(string code1)
{
DateTime time = System.DateTime.Now;
Code1 = code1;
Code1Time = time.ToString();
}
private void RefreshCode2(string code2)
{
DateTime time = System.DateTime.Now;
Code2 = code2;
Code2Time = time.ToString();
}
/// <summary>
/// 提示信息刷新并且存日志
/// </summary>
/// <param name="logStr"></param>
private void RefreshAndWriteLog(string logStr)
{
TimeSpan currentTime = DateTime.Now.TimeOfDay;
// DateTime time = System.DateTime.Now;
string timeString = currentTime.ToString(@"hh\:mm\:ss");
BindingInfo = timeString + ":" + logStr;
log.Info(BindingInfo);
}
/// <summary>
/// 条码绑定
/// </summary>
/// <param name="code1">MES码</param>
/// <param name="code2">SN码</param>
public void BindingCode(string code1, string code2)
{
try
{
if (code1.Substring(0, 1) != "B")
{
RefreshAndWriteLog("MES码:" + code1 + ",扫描错误,请重新扫描!");
SendPlcStop();
return;
}
if (code2.Length != 20)
{
RefreshAndWriteLog("SN码:" + code2 + ",扫描错误,请重新扫描!");
SendPlcStop();
return;
}
RefreshAndWriteLog("开始绑定MES条码:" + code1 + " SN条码:" + code2);
// 1.数据库查询各个工序质检结果,不合格报警
//// 2.查询条码绑定记录表(内胆箱壳绑定处就应该插入记录)绑定SN码
int Repeatflag = 0;
CodeBindingRecord record = _codeBindingRecordServices.FirstAsync(x => x.BoxCode == code1).Result;
if (record == null)
{
RefreshAndWriteLog("未查询到MES条码记录,集存库未绑定箱壳内胆");
//return;
// 没有记录重新插入一条
record = new CodeBindingRecord();
}
else
{
Repeatflag = 1;
}
BaseMaterialInfo materialInfo = _baseMaterialInfoServices.FirstAsync(x => x.MaterialCode == code1.Substring(7, 10)).Result;
if (materialInfo == null)
{
record.BoxName = "";
}
else
{
record.BoxName = materialInfo.MaterialName;
}
record.BoxCode = code1;
record.ProductCode = code2;
//record.RecordTime1 = System.DateTime.Now;
record.RecordTime2 = System.DateTime.Now;
record.isPlcPass = 1;
record.BindingResult = "成功";
bool result = false;
if (Repeatflag == 0)
{ // 没有记录,新加
result = _codeBindingRecordServices.AddAsync(record).Result > 0 ? true : false;
}
else if (Repeatflag == 1)
{
result = _codeBindingRecordServices.UpdateAsync(record).Result;
}
if (result)
{
RefreshAndWriteLog("条码【" + record.BoxCode + "】与SN码【" + record.ProductCode + "】绑定成功");
#region 更新过点数据,插入记录到MATERIAL_COMPLETION表
PrintBarCode print = _printBarCodeServices.FirstAsync(x => x.MaterialBarcode == code1).Result;
if (print == null) return;
MaterialCompletion completion = new MaterialCompletion();
completion.OrderCode = print.OrderCode;
completion.MaterialBarcode = code1;
completion.MaterialCode = print.MaterialCode;
completion.MaterialName = print.MaterialName;
completion.StationName = "1008";
completion.CompleteDate = DateTime.Now;
completion.isDownLine = 0;
completion.ProductLineCode = "CX_02";
_ = _iMaterialCompletionServices.AddAsync(completion).Result;
#endregion
SendPlcPass();
//刷新页面
LoadData();
LoadCharts();
}
else
{
RefreshAndWriteLog("条码【" + record.BoxCode + "】与SN码【" + record.ProductCode + "】绑定失败");
if (SendPlcStop())
{
RefreshAndWriteLog("条码绑定失败,线体停止");
}
}
}
catch (Exception ex)
{
RefreshAndWriteLog(ex.Message.ToString());
SendPlcStop();
}
finally
{
// code1Str = string.Empty;
// code2Str = string.Empty;
}
}
#region plc交互
/// <summary>
/// 下发plc停止信号
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
private bool SendPlcStop()
{
bool result = false;
try
{
var obj = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("条码绑定Plc"));
if (obj != null)
{
log.Info("停止信号D7102写1");
// 往plc写入停止信号
obj.plc.WriteInt16("D7102", "1");
// 报警信号
obj.plc.WriteInt16("D7101", "1");
result = true;
}
}
catch (Exception ex)
{
log.Error("下发plc停止信号方法出现异常,ex:" + ex);
}
return result;
}
/// <summary>
/// 下发plc放行信号
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
private bool SendPlcPass()
{
bool result = false;
try
{
var obj = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("条码绑定Plc"));
if (obj != null)
{
log.Info("下发放行,停止信号D7102写0");
// 停止信号复位
obj.plc.WriteInt16("D7102", "0");
// 报警信号复位
obj.plc.WriteInt16("D7101", "0");
result = true;
}
}
catch (Exception ex)
{
log.Error("下发plc停止信号方法出现异常,ex:" + ex);
}
return result;
}
/// <summary>
/// 发送心跳
/// </summary>
/// <param name="obj"></param>
/// <param name="flag"></param>
private void SendHeart(PlcModel obj, string flag)
{
try
{
// log.Info("心跳D7100写:"+flag);
// 往plc写入停止信号
obj.plc.WriteInt16("D7100", flag);
// obj.plc.WriteInt32("D7102", 1);
}
catch (Exception ex)
{
log.Error("SendHeart异常,ex:" + ex);
}
}
///// <summary>
///// 下发plc放行信号
///// </summary>
///// <param name="materialType"></param>
//private bool SendPlcPass(PlcModel obj)
//{
// bool result = false;
// try
// {
// log.Info("D7100写1");
// // 往plc写入放行信号
// obj.plc.WriteInt16("D7100", "1");
// // 等待plc反馈信号
// result = waitPlcSignal(obj);
// }
// catch (Exception ex)
// {
// log.Error("下发plc放行信号方法SendPlcPass()出现异常,ex:" + ex);
// }
// return result;
//}
///// <summary>
///// 读取plc放行反馈
///// </summary>
///// <param name="materialType"></param>
//private bool waitPlcSignal(PlcModel obj)
//{
// bool result = false;
// try
// {
// DateTime startTime = DateTime.Now;
// bool isFlag = true;
// do
// {
// if (obj.plc.ReadInt16("D7200") == 2)
// {
// log.Info("D7100读2");
// isFlag = false;
// result = true;
// }
// TimeSpan elapsedTime = DateTime.Now - startTime;
// if (elapsedTime.TotalSeconds >= 5)
// {
// isFlag = false;
// }
// Thread.Sleep(500);
// } while (isFlag);
// }
// catch (Exception ex)
// {
// log.Error("读取plc放行反馈方法waitPlcSignal()出现异常,ex:" + ex);
// }
// return result;
//}
#endregion
}
}