LockResult.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using Prism.Mvvm;
  7. using SqlSugar;
  8. using TouchSocket.Core;
  9. namespace TeamAAS_VP.Models
  10. {
  11. public class LockResult : BindableBase
  12. {
  13. private int __Number;
  14. /// <summary>
  15. /// 序号(界面显示用)
  16. /// </summary>
  17. public int Number
  18. {
  19. get { return __Number; }
  20. set { SetProperty(ref __Number, value); }
  21. }
  22. private DateTime __Timestamp;
  23. /// <summary>
  24. /// 时间戳
  25. /// </summary>
  26. public DateTime Timestamp
  27. {
  28. get { return __Timestamp; }
  29. set { SetProperty(ref __Timestamp, value); }
  30. }
  31. private float __LockTurns;
  32. /// <summary>
  33. /// 锁付圈数
  34. /// </summary>
  35. public float LockTurns
  36. {
  37. get { return __LockTurns; }
  38. set { SetProperty(ref __LockTurns, value); }
  39. }
  40. private float __LockTorque;
  41. /// <summary>
  42. /// 锁付扭矩
  43. /// </summary>
  44. public float LockTorque
  45. {
  46. get { return __LockTorque; }
  47. set { SetProperty(ref __LockTorque, value); }
  48. }
  49. private float __LockDuration;
  50. /// <summary>
  51. /// 锁付用时
  52. /// </summary>
  53. public float LockDuration
  54. {
  55. get { return __LockDuration; }
  56. set { SetProperty(ref __LockDuration, value); }
  57. }
  58. private bool __LockPassed;
  59. /// <summary>
  60. /// 锁付结果(是否通过)
  61. /// </summary>
  62. public bool LockPassed
  63. {
  64. get { return __LockPassed; }
  65. set { SetProperty(ref __LockPassed, value); }
  66. }
  67. private int __ScrewdriverProgramNumber;
  68. /// <summary>
  69. /// 电批程序号
  70. /// </summary>
  71. public int ScrewdriverProgramNumber
  72. {
  73. get { return __ScrewdriverProgramNumber; }
  74. set { SetProperty(ref __ScrewdriverProgramNumber, value); }
  75. }
  76. /// <summary>
  77. /// 锁付曲线图片保存路径(为空则不导出)
  78. /// </summary>
  79. [SugarColumn(IsIgnore = true)]
  80. public string LockCurveImagePath { get; set; }
  81. /// <summary>
  82. /// 锁付曲线 CSV 保存路径(数据库关联字段)
  83. /// </summary>
  84. [SugarColumn(IsIgnore = true)]
  85. public string CurveCsvPath { get; set; }
  86. /// <summary>
  87. /// 是否为界面展示用演示数据(不入库、不导出)
  88. /// </summary>
  89. [SugarColumn(IsIgnore = true)]
  90. public bool IsDemoData { get; set; }
  91. /// <summary>
  92. /// 锁付曲线数据列表
  93. /// </summary>
  94. [SugarColumn(IsIgnore = true)]
  95. public List<WaveData> WaveDatas { get; set; } = new List<WaveData>();
  96. public LockResult()
  97. {
  98. // 默认构造函数
  99. Timestamp = DateTime.Now;
  100. }
  101. public LockResult(float lockTurns, float lockTorque, bool lockPassed)
  102. {
  103. Timestamp = DateTime.Now;
  104. LockTurns = lockTurns;
  105. LockTorque = lockTorque;
  106. LockPassed = lockPassed;
  107. }
  108. public LockResult Clone()
  109. {
  110. return new LockResult
  111. {
  112. Number = this.Number,
  113. Timestamp = this.Timestamp,
  114. LockTurns = this.LockTurns,
  115. LockTorque = this.LockTorque,
  116. LockDuration = this.LockDuration,
  117. LockPassed = this.LockPassed,
  118. ScrewdriverProgramNumber = this.ScrewdriverProgramNumber,
  119. LockCurveImagePath = this.LockCurveImagePath,
  120. CurveCsvPath = this.CurveCsvPath,
  121. IsDemoData = this.IsDemoData,
  122. WaveDatas = new List<WaveData>(this.WaveDatas),
  123. };
  124. }
  125. /// <summary>
  126. /// 将当前的锁付结果结果及波形数据存储至.csv文件中
  127. /// </summary>
  128. /// <param name="filePath"></param>
  129. public void SaveToCsv(string filePath)
  130. {
  131. string EscapeCsv(object value)
  132. {
  133. if ( value == null ) return "\"\"";
  134. string s;
  135. if ( value is DateTime dt )
  136. {
  137. s = dt.ToString("o"); // ISO 8601
  138. }
  139. else
  140. {
  141. s = Convert.ToString(value, System.Globalization.CultureInfo.InvariantCulture);
  142. }
  143. s = s.Replace("\"", "\"\""); // escape quotes
  144. return $"\"{s}\"";
  145. }
  146. using ( var writer = new System.IO.StreamWriter(filePath, false, System.Text.Encoding.UTF8) )
  147. {
  148. // 写入锁付结果信息表头(已新增字段)
  149. writer.WriteLine("Number,Timestamp,LockTurns,LockTorque,LockDuration,LockPassed,ScrewdriverProgramNumber");
  150. writer.WriteLine(string.Join(",",
  151. EscapeCsv(Number),
  152. EscapeCsv(Timestamp),
  153. EscapeCsv(LockTurns),
  154. EscapeCsv(LockTorque),
  155. EscapeCsv(LockDuration),
  156. EscapeCsv(LockPassed),
  157. EscapeCsv(ScrewdriverProgramNumber)
  158. ));
  159. // 写入波形数据
  160. writer.WriteLine();
  161. writer.WriteLine("WaveDataIndex,Time,LockAngle,Torque,Turns,Speed,Slopes");
  162. for ( int i = 0; i < WaveDatas.Count; i++ )
  163. {
  164. var waveData = WaveDatas[i];
  165. writer.WriteLine(string.Join(",",
  166. EscapeCsv(i),
  167. EscapeCsv(waveData.Time),
  168. EscapeCsv(waveData.LockAngle),
  169. EscapeCsv(waveData.Torque),
  170. EscapeCsv(waveData.Turns),
  171. EscapeCsv(waveData.Speed),
  172. EscapeCsv(waveData.Slopes)
  173. ));
  174. }
  175. }
  176. }
  177. /// <summary>
  178. /// 异步保存到csv
  179. /// </summary>
  180. /// <param name="filePath"></param>
  181. /// <returns></returns>
  182. public async System.Threading.Tasks.Task SaveToCsvAsync(string filePath)
  183. {
  184. await System.Threading.Tasks.Task.Run(() =>
  185. {
  186. try
  187. {
  188. SaveToCsv(filePath);
  189. }
  190. catch ( Exception ex )
  191. {
  192. LogHelper.WriteLogError("保存锁付数据至CSV时出错!", ex);
  193. }
  194. });
  195. }
  196. }
  197. /// <summary>
  198. /// 曲线数据结构,包含速度、扭矩、角度、圈数、斜率与时间。
  199. /// </summary>
  200. public struct WaveData
  201. {
  202. /// <summary>
  203. /// 速度
  204. /// </summary>
  205. public double Speed { get; set; }
  206. /// <summary>
  207. /// 扭矩
  208. /// </summary>
  209. public double Torque { get; set; }
  210. /// <summary>
  211. /// 角度
  212. /// </summary>
  213. public double LockAngle { get; set; }
  214. /// <summary>
  215. /// 圈数
  216. /// </summary>
  217. public double Turns { get; set; }
  218. /// <summary>
  219. /// 斜率
  220. /// </summary>
  221. public double Slopes { get; set; }
  222. /// <summary>
  223. /// 时间(秒)
  224. /// </summary>
  225. public double Time { get; set; }
  226. }
  227. }