170 lines
5.7 KiB
C#
170 lines
5.7 KiB
C#
using Aurora;
|
|
using Aurora.Api;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Data;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reactive.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using WeldingCommon.Data;
|
|
using WeldingCommon.Devices;
|
|
using WeldingCommon.Settings;
|
|
using WeldingCommon.Utils;
|
|
using WeldingCommon.Utils.Diff;
|
|
|
|
namespace WeldingCommon.Recipes
|
|
{
|
|
public class RecipeChangeHistoryHandler
|
|
{
|
|
protected Logger Log = new Logger("RchHandler", "RecipeChangeHistory_Evnet");
|
|
protected IAuroraEnvironment _aurora;
|
|
protected IRecipeEntry _recipeEntry;
|
|
protected SystemParameter _settingParameter;
|
|
|
|
protected readonly object _historyLock = new object();
|
|
|
|
public ObservableCollection<RecipeHistory> HistoryDatas { get; set; } = new ObservableCollection<RecipeHistory>();
|
|
|
|
private string _currentDateKey; // yyyyMMdd
|
|
|
|
private string GetDateKey(DateTime t) => t.ToString("yyyyMMdd", CultureInfo.InvariantCulture);
|
|
|
|
private string GetDailyFilePath(string dateKey)
|
|
{
|
|
var dir = _settingParameter.RecipeHistoryFolderPath;
|
|
if (!string.IsNullOrEmpty(dir))
|
|
Directory.CreateDirectory(dir);
|
|
|
|
return Path.Combine(dir, $"RecipeInfo_{dateKey}.ndjson");
|
|
}
|
|
|
|
public void RegistryDeviceHandler(IAuroraEnvironment aurora)
|
|
{
|
|
_aurora = aurora;
|
|
_recipeEntry = aurora.RecipeManager;
|
|
_settingParameter = _aurora.SettingEntry[CommonSettingIds.SystemParameter] as SystemParameter;
|
|
|
|
EnsureDailyContext(DateTime.Now);
|
|
}
|
|
|
|
public void AppendChangedItem(string recipeName, ObservableCollection<PropertyDiff> diffs)
|
|
{
|
|
lock (_historyLock) {
|
|
var now = DateTime.Now;
|
|
EnsureDailyContext(now);
|
|
|
|
var item = new RecipeHistory {
|
|
Timestamp = now,
|
|
RecipeName = recipeName,
|
|
Changes = diffs.Select(d => d.ToString()).ToList()
|
|
};
|
|
|
|
HistoryDatas.Add(item);
|
|
|
|
AppendNdjsonLine(GetDailyFilePath(_currentDateKey), item);
|
|
}
|
|
}
|
|
|
|
|
|
private void EnsureDailyContext(DateTime today)
|
|
{
|
|
var key = GetDateKey(today);
|
|
if (_currentDateKey == key)
|
|
return;
|
|
|
|
_currentDateKey = key;
|
|
|
|
HistoryDatas.Clear();
|
|
|
|
var path = GetDailyFilePath(key);
|
|
LoadNdjson(path, HistoryDatas);
|
|
}
|
|
|
|
private void AppendNdjsonLine(string path, RecipeHistory item)
|
|
{
|
|
var json = JsonConvert.SerializeObject(item);
|
|
|
|
using (var fs = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)) {
|
|
using (var sw = new StreamWriter(fs, new UTF8Encoding(encoderShouldEmitUTF8Identifier: true))) {
|
|
sw.WriteLine(json);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void LoadNdjson(string path, ObservableCollection<RecipeHistory> target)
|
|
{
|
|
if (!File.Exists(path))
|
|
return;
|
|
|
|
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
|
|
using (var sr = new StreamReader(fs, new UTF8Encoding(encoderShouldEmitUTF8Identifier: true))) {
|
|
string line;
|
|
while ((line = sr.ReadLine()) != null) {
|
|
if (string.IsNullOrWhiteSpace(line))
|
|
continue;
|
|
|
|
try {
|
|
var item = JsonConvert.DeserializeObject<RecipeHistory>(line);
|
|
if (item != null)
|
|
target.Add(item);
|
|
} catch {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public ObservableCollection<RecipeHistory> FromStartToEndHistory(DateTime start, DateTime end)
|
|
{
|
|
if (end < start) {
|
|
var tmp = start;
|
|
start = end;
|
|
end = tmp;
|
|
}
|
|
|
|
var result = new List<RecipeHistory>();
|
|
var day = start.Date;
|
|
var lastDay = end.Date;
|
|
|
|
lock (_historyLock) {
|
|
while (day <= lastDay) {
|
|
var key = GetDateKey(day);
|
|
var path = GetDailyFilePath(key);
|
|
|
|
if (File.Exists(path)) {
|
|
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
|
using (var sr = new StreamReader(fs, new UTF8Encoding(encoderShouldEmitUTF8Identifier: true))) {
|
|
string line;
|
|
while ((line = sr.ReadLine()) != null) {
|
|
if (string.IsNullOrWhiteSpace(line))
|
|
continue;
|
|
|
|
try {
|
|
var item = JsonConvert.DeserializeObject<RecipeHistory>(line);
|
|
if (item == null)
|
|
continue;
|
|
|
|
//if (item.Timestamp >= start && item.Timestamp <= end)
|
|
result.Add(item);
|
|
} catch {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
day = day.AddDays(1);
|
|
}
|
|
|
|
var ordered = result.OrderByDescending(x => x.Timestamp);
|
|
|
|
return new ObservableCollection<RecipeHistory>(ordered);
|
|
}
|
|
}
|
|
}
|
|
}
|