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.
haoliang-net/Core/ProductionTracker.cs

105 lines
4.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Data;
using Dapper;
using MySql.Data.MySqlClient;
using CncModels.Enum;
using CncModels.Entity;
using log4net;
namespace CncCollector.Core
{
/// <summary>
/// 零件产量分段跟踪引擎:维护内存中的活跃段状态,并定期写入数据库。
/// </summary>
public class ProductionTracker
{
private readonly string _connectionString;
private readonly object _lock = new object();
private static readonly ILog Log = LogManager.GetLogger(typeof(ProductionTracker));
public ProductionTracker(string connectionString)
{
_connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString));
}
/// <summary>
/// 处理一个采集记录后的产量跟踪逻辑。
/// </summary>
public void Track(int machineId, string programName, int partCount, DateTime collectTime)
{
lock (_lock)
{
using (var conn = new MySqlConnection(_connectionString))
{
conn.Open();
// 查找当前未结算的活跃段
var active = conn.QueryFirstOrDefault<ProductionSegment>(
"SELECT * FROM cnc_production_segment WHERE machine_id=@MachineId AND is_settled=0 AND end_time IS NULL",
new { MachineId = machineId });
if (active == null)
{
// 开新段
const string sqlStart = @"INSERT INTO cnc_production_segment
(machine_id, program_name, production_date, start_time, start_part_count, is_settled)
VALUES
(@MachineId, @ProgramName, @ProductionDate, @StartTime, @StartPartCount, 0)";
conn.Execute(sqlStart, new
{
MachineId = machineId,
ProgramName = programName,
ProductionDate = collectTime.Date,
StartTime = collectTime,
StartPartCount = partCount
});
}
else
{
// 程序名变更则结账并开新段
if (!string.Equals(active.ProgramName, programName, StringComparison.OrdinalIgnoreCase))
{
const string sqlClose = @"UPDATE cnc_production_segment
SET end_time=@EndTime, end_part_count=@EndPartCount, is_settled=1, close_reason=@Reason
WHERE id=@Id";
conn.Execute(sqlClose, new
{
EndTime = collectTime,
EndPartCount = active.EndPartCount ?? active.StartPartCount,
Id = active.Id,
Reason = SegmentCloseReason.ProgramChange.ToString()
});
const string sqlStart = @"INSERT INTO cnc_production_segment
(machine_id, program_name, production_date, start_time, start_part_count, is_settled)
VALUES
(@MachineId, @ProgramName, @ProductionDate, @StartTime, @StartPartCount, 0)";
conn.Execute(sqlStart, new
{
MachineId = machineId,
ProgramName = programName,
ProductionDate = collectTime.Date,
StartTime = collectTime,
StartPartCount = partCount
});
}
else
{
// 更新当前段的结束时间与结束时的部件数
const string sqlUpdate = @"UPDATE cnc_production_segment
SET end_time=@EndTime, end_part_count=@EndPartCount
WHERE id=@Id";
conn.Execute(sqlUpdate, new
{
EndTime = collectTime,
EndPartCount = partCount,
Id = active.Id
});
}
}
}
}
}
}
}