DBInfoTraceViewModel.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. using Mapster;
  2. using OpenTK.Graphics.ES20;
  3. using ProximaAnalizer.Helpers;
  4. using ScottPlot;
  5. using ScottPlot.Plottables;
  6. using ScottPlot.WPF;
  7. using SqlSugar;
  8. using System.Windows;
  9. using System.Windows.Media;
  10. using Universal;
  11. namespace ProximaAnalizer.ViewModels;
  12. internal partial class DBInfoTraceViewModel : ObservableObject
  13. {
  14. public DBInfoTraceViewModel(TraceData traceData,
  15. SqlSugarCustom sqlSugarCustom,
  16. IEventAggregator eventAggregator,
  17. IDialogService dialogService)
  18. {
  19. this.traceData = traceData;
  20. this.sqlSugarCustom = sqlSugarCustom;
  21. this.dialogService = dialogService;
  22. this.Left = [];
  23. this.Right = [];
  24. this.PlotControl = new();
  25. this._DBDisplayHelper = new(Left, Right);
  26. this._PlotHelper = new(this.PlotControl);
  27. this._PlotHelper.InitPlot();
  28. eventAggregator.GetEvent<RefreshRecipeData>().Subscribe(Search);
  29. }
  30. private readonly TraceData traceData;
  31. private readonly SqlSugarCustom sqlSugarCustom;
  32. private readonly IDialogService dialogService;
  33. private readonly PlotHepler _PlotHelper;
  34. private readonly DBDisplayHelper _DBDisplayHelper;
  35. [ObservableProperty]
  36. private WpfPlot _PlotControl;
  37. [ObservableProperty]
  38. private ObservableDictionary<DateTime, SelectRecipeStep> _RecipeSteps = [];
  39. [ObservableProperty]
  40. private IDictionary<string, object>? _Hierachy;
  41. [ObservableProperty]
  42. private ObservableDictionary<string, object> _Left = [];
  43. [ObservableProperty]
  44. private ObservableDictionary<string, object> _Right = [];
  45. private readonly Stack<IDictionary<string, object>> Cache = new();
  46. [ObservableProperty]
  47. private bool _DisplayAlarm = false;
  48. private bool AutoGenerated = false;
  49. [RelayCommand]
  50. private void Selected(SelectRecipeStep step)
  51. {
  52. if (RecipeSteps is null)
  53. return;
  54. if (sqlSugarCustom.Client is null)
  55. return;
  56. if (AutoGenerated)
  57. {
  58. UnSelected(step);
  59. return;
  60. }
  61. if (RecipeSteps.Where(t => t.Value.IsSelected).Count() != 2)
  62. return;
  63. DateTime start = RecipeSteps.Where(t => t.Value.IsSelected).First().Key;
  64. DateTime end = RecipeSteps.Where(t => t.Value.IsSelected).Last().Key;
  65. RecipeSteps.Where(t => t.Key >= start && t.Key <= end).Foreach(t => t.Value.IsSelected = true);
  66. this.AutoGenerated = true;
  67. }
  68. [RelayCommand]
  69. private void UnSelected(SelectRecipeStep step)
  70. {
  71. RecipeSteps.Where(t => t.Value.IsSelected).Foreach(t => t.Value.IsSelected = false);
  72. this.AutoGenerated = false;
  73. }
  74. [RelayCommand]
  75. private void SelectHierachy(KeyValuePair<string, object> item)
  76. {
  77. if (this.Hierachy is null)
  78. return;
  79. if (item.Value is IDictionary<string, object> next)
  80. {
  81. this.Cache.Push(this.Hierachy);
  82. this.Hierachy = next;
  83. return;
  84. }
  85. //this.Left.TryAdd((string)item.Value, item.Value);
  86. //IDialogParameters parameters, Action< IDialogResult > callback
  87. IDialogParameters para = new DialogParameters() { { "Line", item.Value } };
  88. dialogService.Show("LinePicker", para, AddLineCallback);
  89. }
  90. [RelayCommand]
  91. private void EditLine(KeyValuePair<string, object> item)
  92. {
  93. IDialogParameters para = new DialogParameters() { { "Line", item.Key } };
  94. dialogService.Show("LinePicker", para, AddLineCallback);
  95. }
  96. private void AddLineCallback(IDialogResult dialogResult)
  97. {
  98. dialogResult.Parameters.TryGetValue("Line", out LineType? lineType);
  99. dialogResult.Parameters.TryGetValue("Name", out string? line);
  100. dialogResult.Parameters.TryGetValue("Axis", out string? Axis);
  101. if (lineType is null || string.IsNullOrEmpty(line) || string.IsNullOrEmpty(Axis))
  102. return;
  103. ObservableDictionary<string, object>? lineCollection = Axis switch
  104. {
  105. "L" => Left,
  106. "R" => Right,
  107. _ => default
  108. };
  109. if (lineCollection is null)
  110. return;
  111. if (lineCollection.TryGetValue(line, out object? oldType) && oldType is LineType oldLine)
  112. oldLine.IsEnable = true;
  113. lineCollection[line] = lineType;
  114. }
  115. [RelayCommand]
  116. private void Return()
  117. {
  118. if (this.Cache.TryPop(out var output) && output is not null)
  119. this.Hierachy = output;
  120. }
  121. [RelayCommand]
  122. private void Search()
  123. {
  124. if (traceData.ProcessData is null)
  125. return;
  126. if (sqlSugarCustom.Client is null)
  127. return;
  128. this.Cache.Clear();
  129. this.RecipeSteps ??= [];
  130. this.RecipeSteps.Clear();
  131. this.Clear(string.Empty);
  132. DateTime beginTime = traceData.ProcessData.Process_Begin_Time;
  133. DateTime endTime = traceData.ProcessData.Process_End_Time;
  134. long beginTicks = beginTime.Ticks;
  135. long endTicks = endTime.Ticks;
  136. List<RecipeStepData> recipeSteps;
  137. try
  138. {
  139. recipeSteps = sqlSugarCustom.Client.Queryable<RecipeStepData>().AS("recipe_step_data")
  140. .Where(t => t.Process_Data_Guid == traceData.ProcessData.Guid)
  141. .OrderBy(t => t.Step_Begin_Time).ToList();
  142. }
  143. catch
  144. {
  145. MessageBox.Show($"recipe_step_data 记录不存在", "Warning", MessageBoxButton.OK, MessageBoxImage.Error);
  146. return;
  147. }
  148. if (recipeSteps.Count == 0)
  149. {
  150. MessageBox.Show($"recipe_step 步骤数量为0", "Warning", MessageBoxButton.OK, MessageBoxImage.Error);
  151. return;
  152. }
  153. foreach (var item in recipeSteps)
  154. {
  155. SelectRecipeStep step = new();
  156. item.Adapt(step);
  157. this.RecipeSteps.TryAdd(item.Step_Begin_Time, step);
  158. }
  159. dynamic pm;
  160. dynamic system;
  161. try
  162. {
  163. pm = sqlSugarCustom.Client.Queryable<dynamic>().AS($"\"{beginTime:yyyyMMdd}.PM1\"").First();
  164. system = sqlSugarCustom.Client.Queryable<dynamic>().AS($"\"{beginTime:yyyyMMdd}.System\"").First();
  165. }
  166. catch
  167. {
  168. MessageBox.Show($"{beginTime:yyyyMMdd} 记录不存在", "Warning", MessageBoxButton.OK, MessageBoxImage.Error);
  169. return;
  170. }
  171. GeneralProcessData processData = new();
  172. if (pm is not IDictionary<string, object> input)
  173. return;
  174. if (!processData.ToDictionary(input, out Dictionary<string, object>? output) || output is null)
  175. return;
  176. if (output["PM1"] is not IDictionary<string, object> pmData)
  177. return;
  178. if (!processData.ToDictionary(system, out Dictionary<string, object>? systemDic) || systemDic is null)
  179. return;
  180. Dictionary<string, object> temp = [];
  181. Dictionary<string, object> PM1 = [];
  182. Dictionary<string, object> System = [];
  183. temp.Add("PM1", PM1);
  184. temp.Add("System", System);
  185. processData.CreateTablePM(pmData, PM1);
  186. processData.CreateTableSystem(systemDic!, System);
  187. this.Hierachy = temp;
  188. this.Cache.Push(temp);
  189. }
  190. [RelayCommand]
  191. private void RemoveLeft(string key)
  192. {
  193. this.Left.TryRemove(key, out object? line);
  194. if (line is LineType lineType)
  195. lineType.IsEnable = true;
  196. }
  197. [RelayCommand]
  198. private void RemoveRight(string key)
  199. {
  200. this.Right.TryRemove(key, out object? line);
  201. if (line is LineType lineType)
  202. lineType.IsEnable = true;
  203. }
  204. [RelayCommand]
  205. private void Clear(string para)
  206. {
  207. switch (para)
  208. {
  209. case "L":
  210. this.Left.Foreach(t => ((LineType)t.Value).IsEnable = true);
  211. this.Left.Clear();
  212. break;
  213. case "R":
  214. this.Right.Foreach(t => ((LineType)t.Value).IsEnable = true);
  215. this.Right.Clear();
  216. break;
  217. default:
  218. this.Right.Foreach(t => ((LineType)t.Value).IsEnable = true);
  219. this.Right.Clear();
  220. this.Left.Foreach(t => ((LineType)t.Value).IsEnable = true);
  221. this.Left.Clear();
  222. break;
  223. }
  224. }
  225. [RelayCommand]
  226. private void GeneratePlot()
  227. {
  228. if (this.sqlSugarCustom.Client is null)
  229. return;
  230. if (!this.RecipeSteps.Any(t => t.Value.IsSelected))
  231. return;
  232. DateTime startTime = this.RecipeSteps.Where(t => t.Value.IsSelected).First().Key;
  233. DateTime endTime = this.RecipeSteps.Where(t => t.Value.IsSelected).Last().Key;
  234. ObjectFuncModel whereFunc = ObjectFuncModel.Create("Format", "time", ">", "{long}:" + $"{startTime.Ticks}", "&&", "time", "<", "{long}:" + $"{endTime.Ticks}");
  235. List<dynamic> pm1 = sqlSugarCustom.Client.Queryable<dynamic>().AS($"\"{startTime:yyyyMMdd}.PM1\"").Where(whereFunc).ToList();
  236. List<dynamic> system = sqlSugarCustom.Client.Queryable<dynamic>().AS($"\"{startTime:yyyyMMdd}.System\"").Where(whereFunc).ToList();
  237. this._DBDisplayHelper.ClearData();
  238. this._DBDisplayHelper.CreateData(pm1, system);
  239. this.PlotControl.Plot.Clear();
  240. foreach (var item in this._DBDisplayHelper.DataLeft)
  241. this._PlotHelper.AddLeftLine(this._DBDisplayHelper.Time, item.Value, ((LineType)Left[item.Key])!.LinePattern, MarkerStyle.None, 1.5f, ((LineType)Left[item.Key])!.HexRGB);
  242. foreach (var item in this._DBDisplayHelper.DataRight)
  243. this._PlotHelper.AddRightLine(this._DBDisplayHelper.Time, item.Value, ((LineType)Right[item.Key])!.LinePattern, MarkerStyle.None, 1.5f, ((LineType)Right[item.Key])!.HexRGB);
  244. if (this.DisplayAlarm)
  245. this.CreateAlarm(startTime, endTime);
  246. this.PlotControl.Plot.Axes.AutoScale();
  247. this.PlotControl.Refresh();
  248. }
  249. private void CreateAlarm(DateTime start, DateTime end)
  250. {
  251. if (this.sqlSugarCustom is null || sqlSugarCustom.Client is null)
  252. return;
  253. List<EventData> alarm = sqlSugarCustom.Client.Queryable<EventData>().AS($"event_data").Where(t => t.Occur_Time >= start && t.Occur_Time <= end && (t.Level == "Alarm" || t.Level == "Warning")).ToList();
  254. if (alarm is null)
  255. return;
  256. alarm.Foreach(item => _ = item.Level switch
  257. {
  258. "Alarm" => this._PlotHelper.AddAlarmLine(item.Occur_Time, $"{item.Source}"),
  259. "Warning" => this._PlotHelper.AddWarningLine(item.Occur_Time, $"{item.Source}"),
  260. _ => true
  261. });
  262. }
  263. [RelayCommand]
  264. private void ViewTraceData()
  265. {
  266. IDialogParameters para = new DialogParameters
  267. {
  268. { "Data", this._DBDisplayHelper},
  269. };
  270. this.dialogService.Show("TraceData", para, null);
  271. }
  272. [RelayCommand]
  273. private void ReScale(string para)
  274. {
  275. switch (para)
  276. {
  277. case "+":
  278. this.PlotControl.Plot.Axes.Zoom(1.25, 1);
  279. break;
  280. case "-":
  281. this.PlotControl.Plot.Axes.Zoom(0.8, 1);
  282. break;
  283. case "add":
  284. this.PlotControl.Plot.Axes.Zoom(1, 1.25);
  285. break;
  286. case "minus":
  287. this.PlotControl.Plot.Axes.Zoom(1, 0.8);
  288. break;
  289. default:
  290. this.PlotControl.Plot.Axes.AutoScale();
  291. this.PlotControl.Plot.Axes.Zoom(1.085, 1);
  292. break;
  293. }
  294. this.PlotControl.Refresh();
  295. }
  296. }
  297. public partial class SelectRecipeStep : ObservableObject
  298. {
  299. [ObservableProperty]
  300. private bool _IsSelected;
  301. public string? Guid { get; set; }
  302. public DateTime Step_Begin_Time { get; set; }
  303. public DateTime Step_End_Time { get; set; }
  304. public string? Step_Name { get; set; }
  305. public float Step_Time { get; set; }
  306. public int Step_Number { get; set; }
  307. public string? Sub_Recipe_Step_Time { get; set; }
  308. public string? Sub_Recipe_Step_Number { get; set; }
  309. public string? Sub_Recipe_Step_Name { get; set; }
  310. public string? Sub_Recipe_Loop_Info { get; set; }
  311. public string? Temp_correction { get; set; }
  312. public string? Temp_pid { get; set; }
  313. }