frmMain.cs 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063
  1. using com.hnshituo.core.webapp.vo;
  2. using Newtonsoft.Json;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.ComponentModel;
  6. using System.Data;
  7. using System.Diagnostics;
  8. using System.Drawing;
  9. using System.Drawing.Drawing2D;
  10. using System.IO;
  11. using System.Linq;
  12. using System.Net.NetworkInformation;
  13. using System.Runtime.InteropServices;
  14. using System.Text;
  15. using System.Threading;
  16. using System.Threading.Tasks;
  17. using System.Windows.Forms;
  18. namespace CarLocalMeter
  19. {
  20. public partial class frmMain : Form
  21. {
  22. public frmMain()
  23. {
  24. InitializeComponent();
  25. }
  26. Log lg = Log.GetInstance();
  27. private LED_Control led_controler;
  28. //List<CamerEs> lc = new List<CamerEs>();
  29. /// <summary>
  30. /// 硬盘录像机图片抓拍通道
  31. /// </summary>
  32. List<int> lc = new List<int>();
  33. /// <summary>
  34. /// 服务端委托获取
  35. /// </summary>
  36. private PreTrackScaleService PreTrackScaleService = new PreTrackScaleService();
  37. RESTfulResult<List<PreTrackScale>> rmScaleListCarTimer = new RESTfulResult<List<PreTrackScale>>();
  38. private MeterWorkCarActualFirstService workCarActualFirstService = new MeterWorkCarActualFirstService(); //一次计量数据
  39. RESTfulResult<List<MeterWorkCarActualFirst>> RESTfulResultOutTimer = new RESTfulResult<List<MeterWorkCarActualFirst>>();
  40. MeterBaseRfidInfoService rfidServer = new MeterBaseRfidInfoService();
  41. PlcCls plc = new PlcCls();
  42. /// <summary>
  43. /// redis操作类
  44. /// </summary>
  45. RedisOption redis = new RedisOption();
  46. /// <summary>
  47. /// 图片操作类
  48. /// </summary>
  49. ImageOption imgControl = new ImageOption();
  50. /// <summary>
  51. /// 重量采集类
  52. /// </summary>
  53. MoxaCls mx = new MoxaCls();
  54. /// <summary>
  55. /// 语音播放
  56. /// </summary>
  57. VoicePlay vicPlayClass = new VoicePlay();
  58. /// <summary>
  59. /// 摄像头车号识别枪机
  60. /// </summary>
  61. CarNoCls carCls = new CarNoCls();
  62. /// <summary>
  63. /// 摄像头识别球机
  64. /// </summary>
  65. CarNoCls carCls2 = new CarNoCls();
  66. /// <summary>
  67. /// rfid车号识别
  68. /// </summary>
  69. RfIdCarNo rfid = new RfIdCarNo();
  70. /// <summary>
  71. /// 以下是硬盘录像机的控制
  72. /// </summary>
  73. bool bVoice = false;
  74. CamerEs ce = new CamerEs(AppConfigCache.voicePlayIp, $"{AppConfigCache.voicePlayPort}", AppConfigCache.voicePlayUid, AppConfigCache.voicePlayPwd);
  75. List<int> voPlay = new List<int>();
  76. int iPic = 0;
  77. private void frmMain_Load(object sender, EventArgs e)
  78. {
  79. CacleCls.updateRfidInfoTime = DateTime.Now;
  80. btnSave.Enabled = false;
  81. if (!string.IsNullOrEmpty(AppConfigCache.ledIp))
  82. {
  83. led_controler = new LED_Control(AppConfigCache.ledIp);
  84. }
  85. #region 读取音频文件名称
  86. List<string> ls = new List<string>();
  87. DirectoryInfo folder = new DirectoryInfo(AppConfigCache.path + "\\Sound");
  88. foreach (FileInfo file in folder.GetFiles("*.wav"))
  89. {
  90. ls.Add(file.Name.Replace(".wav", ""));
  91. }
  92. CacleCls.voiceInfo = ls;
  93. #endregion
  94. string[] strTd1 = AppConfigCache.channelOther.Split(',');
  95. string[] strTd2 = AppConfigCache.channelVis.Split(',');
  96. string[] strAll = new string[strTd1.Length + strTd2.Length];
  97. strTd1.CopyTo(strAll, 0);
  98. strTd2.CopyTo(strAll, strTd1.Length);
  99. List<string> lcs = strAll.Distinct().OrderBy(s => s).ToList(); //
  100. lc.Add(AppConfigCache.channelCarNo);
  101. foreach (string str in lcs)
  102. {
  103. if ($"{AppConfigCache.channel}" != str && $"{AppConfigCache.channelCarNo}" != str)
  104. {
  105. lc.Add(Convert.ToInt32(str)); //抓拍通道与数组中不相同的时候写入,因为我们仪表抓拍的通道需单独进行处理
  106. }
  107. }
  108. plImgShow.Visible = false;
  109. lbPointName.Text = AppConfigCache.pointName;
  110. foreach (string str in AppConfigCache.channelVis.Split(','))
  111. {
  112. voPlay.Add(Convert.ToInt32(str));
  113. }
  114. ce.Connection();
  115. foreach(int i in voPlay)
  116. {
  117. PictureBox pb = new PictureBox();
  118. pb.Dock = DockStyle.Top;
  119. pb.DoubleClick += new EventHandler(PictureBoxDoubleClick);
  120. pb.Height = AppConfigCache.channelVisHeight;
  121. pb.Name = $"pb{i}";
  122. panel1.Controls.Add(pb);
  123. ce.RealPlay(pb, i);
  124. }
  125. mx.start();
  126. TaskPing();
  127. /*
  128. rfid.Start();
  129. TaskMain();
  130. TaskDbUpload();
  131. imgControl.Start();
  132. plc.Start();
  133. carCls.Login(AppConfigCache.voiceCarNoIp, AppConfigCache.voiceCarNoPort, AppConfigCache.voiceCarNoUid, AppConfigCache.voiceCarNoPwd);
  134. //*/
  135. //carCls2.Login(AppConfigCache.voiceCarNoIp2, AppConfigCache.voiceCarNoPort2, AppConfigCache.voiceCarNoUid2, AppConfigCache.voiceCarNoPwd2, false);
  136. }
  137. CancellationTokenSource _cts,_cts2,_dbCts;
  138. bool getPreInfo = false, getFirst = false, flagCaption = false, isVoiceDownCar = false;
  139. string strOldCarNo = "";
  140. bool isMeasureSuccess = false;
  141. int voiceNum = 0;
  142. int iImgCnt = 0;
  143. /// <summary>
  144. /// 主定时任务
  145. /// </summary>
  146. private void TaskMain()
  147. {
  148. _cts = new CancellationTokenSource();
  149. Task.Run(() => {
  150. while (!_cts.IsCancellationRequested)
  151. {
  152. this.panel3.Invoke(new Action(() => {
  153. if (!CacleCls.isLock)
  154. {
  155. ucWeightT1.setWgt(Math.Round((double)CacleCls.weight / 1000, 2)); //2021年5月10日界面显示单位,调整为T
  156. ucWeightT1.setStable(CacleCls.isWd != 1 ? true : false);
  157. ucWeightT1.setExceed(CacleCls.weight > AppConfigCache.maxRange * 1000 ? false : true);
  158. if (cbCarNo.Text.Trim() != "" && txtCarNo.Text.Trim() != "")
  159. {
  160. CacleCls.lockCarNo = cbCarNo.Text.Trim() + txtCarNo.Text.Trim();
  161. }
  162. else if (CacleCls.rfidCarNo != "")
  163. {
  164. CacleCls.lockCarNo = CacleCls.rfidCarNo;
  165. }
  166. else if (CacleCls.voicCarNo != "")
  167. {
  168. CacleCls.lockCarNo = CacleCls.voicCarNo;
  169. }
  170. else if (!string.IsNullOrEmpty(CacleCls.voicCarNo2))
  171. {
  172. CacleCls.lockCarNo = CacleCls.voicCarNo2;
  173. }
  174. if (CacleCls.lockCarNo != "" && cbCarNo.Text.Trim() == "" && txtCarNo.Text.Trim() == "")
  175. {
  176. cbCarNo.Text = CacleCls.lockCarNo.Substring(0, 1);
  177. if (CacleCls.lockCarNo.Length > 1)
  178. {
  179. txtCarNo.Text = CacleCls.lockCarNo.Substring(1);
  180. }
  181. }
  182. if (strOldCarNo != CacleCls.lockCarNo)
  183. {
  184. strOldCarNo = CacleCls.lockCarNo;
  185. getPreInfo = false;
  186. getFirst = false;
  187. }
  188. }
  189. if (CacleCls.weight > 500)
  190. {
  191. iImgCnt = 0;
  192. CacleCls.isClear = false;
  193. //是否能连上远程服务器,这里只是服务器,不是服务器上的服务端
  194. pbLineOn.Load(CacleCls.serverFlag ? (AppConfigCache.path + "\\image\\icon\\green.gif") : (AppConfigCache.path + "\\image\\icon\\red.gif"));
  195. #region 一些必要验证及提醒
  196. if (!CacleCls.isLock)
  197. {
  198. //重量最后一位不为0也是超量程
  199. if ((AppConfigCache.maxRange * 1000 < CacleCls.weight) || CacleCls.weight.ToString().Substring(CacleCls.weight.ToString().Length - 1, 1) != "0")
  200. {
  201. //超量程
  202. vicPlayClass.GetVoicePlay("已超量程", CacleCls.lockCarNo);
  203. txtMsgInfo.Text = "当前重量已超量程,秤体量程为【" + AppConfigCache.maxRange + "】T,不允许进行自助计量操作!";
  204. led_controler.setStaticLineMsg(AppConfigCache.ledIp, "当前重量已超量程,秤体量程为【" + AppConfigCache.maxRange + "】T,不允许进行自助计量操作!");
  205. CacleCls.isLock = false;
  206. return;
  207. }
  208. if (CacleCls.isWd == 0 && !string.IsNullOrEmpty(CacleCls.lockCarNo))
  209. {
  210. if ((CacleCls.topJg == "1" || CacleCls.bottomJg == "1"))
  211. {
  212. //重量稳定,且对射验证不合格
  213. vicPlayClass.GetVoicePlay("车辆超出秤台,请调整车位2", CacleCls.lockCarNo);
  214. txtMsgInfo.Text = "车辆超出秤台,请调整车位2";
  215. led_controler.setStaticLineMsg(AppConfigCache.ledIp, "车辆超出秤台,请调整车位2");
  216. CacleCls.isLock = false;
  217. return;
  218. }
  219. else if (CacleCls.rightGs == "1")
  220. {
  221. //重量稳定,且右光栅不合格
  222. vicPlayClass.GetVoicePlay("车辆超出秤台,请调整车位3", CacleCls.lockCarNo);
  223. txtMsgInfo.Text = "车辆超出秤台,请调整车位3";
  224. led_controler.setStaticLineMsg(AppConfigCache.ledIp, "车辆超出秤台,请调整车位3");
  225. CacleCls.isLock = false;
  226. return;
  227. }
  228. else if (CacleCls.leftGs == "1")
  229. {
  230. //重量稳定,且左光栅不合格
  231. vicPlayClass.GetVoicePlay("车辆超出秤台,请调整车位4", CacleCls.lockCarNo);
  232. txtMsgInfo.Text = "车辆超出秤台,请调整车位4";
  233. led_controler.setStaticLineMsg(AppConfigCache.ledIp, "车辆超出秤台,请调整车位4");
  234. CacleCls.isLock = false;
  235. return;
  236. }
  237. }
  238. /*
  239. if (PbCache.isOvertimeAlarm)
  240. {
  241. //停留超时提醒,不作为计量卡控的条件
  242. if (!isPlayOvertimeVoice && !PbCache.isLockFrm)
  243. {
  244. vicPlayClass.GetVoicePlay("停留超时", PbCache.collect.carno);
  245. led_controler.setStaticLineMsg(PbCache.sportInfo.ledIp, "停留超时");
  246. txtMsgInfo.Text = "停留超时";
  247. PbCache.ResultMessage = "停留超时";
  248. isPlayOvertimeVoice = true;
  249. return;
  250. }
  251. }
  252. //*/
  253. #region 一次计量数据跟预报获取一次
  254. if (!string.IsNullOrEmpty(CacleCls.lockCarNo))
  255. {
  256. //查询一次计量数据
  257. if (!getFirst)
  258. {
  259. RESTfulResultOutTimer = workCarActualFirstService.doQueryWf(new MeterWorkCarActualFirst { valueFlag = "1", carNo = CacleCls.lockCarNo });
  260. if (RESTfulResultOutTimer.Succeed)
  261. {
  262. if (RESTfulResultOutTimer.Data != null && RESTfulResultOutTimer.Data.Count > 0)
  263. {
  264. CacleCls.firstDb = RESTfulResultOutTimer.Data[0];
  265. if (CacleCls.firstDb.predictionNo != null && !CacleCls.firstDb.predictionNo.Contains("_"))
  266. {
  267. txtMATTER_NAME.Text = CacleCls.firstDb.matterName;
  268. txtFORWARDING_UNIT_NAME.Text = CacleCls.firstDb.forwardingUnitName;
  269. txtRECEIVING_UINT_NAME.Text = CacleCls.firstDb.receivingUintName;
  270. txtMETER_TYPE.Text = CacleCls.firstDb.meterTypeName;
  271. }
  272. }
  273. }
  274. getFirst = true;
  275. }
  276. //根据网络状态及车号以及是否存在一次计量数据,查询一次预报信息,然后将getPreInfo改为true
  277. if (!getPreInfo && CacleCls.serverFlag)
  278. {
  279. if (CacleCls.firstDb == null || string.IsNullOrEmpty(CacleCls.firstDb?.predictionNo))
  280. {
  281. //如果没有一次信息或者一次信息里面没带预报信息,则查询一次预报信息
  282. rmScaleListCarTimer = PreTrackScaleService.doQueryByFlag(new PreTrackScale { lineDesc = "1", carNo = CacleCls.lockCarNo });
  283. if (rmScaleListCarTimer.Succeed)
  284. {
  285. if (rmScaleListCarTimer.Data != null && rmScaleListCarTimer.Data.Count == 1)
  286. {
  287. CacleCls.preTrackScale = rmScaleListCarTimer.Data[0];
  288. txtMATTER_NAME.Text = CacleCls.preTrackScale.matterName;
  289. txtFORWARDING_UNIT_NAME.Text = CacleCls.preTrackScale.forwardingUnitName;
  290. txtRECEIVING_UINT_NAME.Text = CacleCls.preTrackScale.receivingUintName;
  291. txtMETER_TYPE.Text = CacleCls.preTrackScale.meterTypeName;
  292. }
  293. }
  294. }
  295. getPreInfo = true;
  296. }
  297. }
  298. #endregion
  299. //进行计量称重条件的判断 车号不为空、重量稳定、车辆已停到位
  300. if (!string.IsNullOrEmpty(CacleCls.lockCarNo) && CacleCls.isWd == 0 && CacleCls.leftGs != "1" && CacleCls.rightGs != "1" && CacleCls.topJg != "1" && CacleCls.bottomJg != "1")
  301. {
  302. if (!isVoiceDownCar)
  303. {
  304. isVoiceDownCar = true;
  305. vicPlayClass.GetVoicePlay("车上人员请下车", CacleCls.lockCarNo);//只播放一次
  306. }
  307. //if(!btnSave.Enabled) btnSave.Enabled = true;
  308. if (!CacleCls.isJg)
  309. {
  310. lg.WriteLog(LogType.SystemLog, CacleCls.lockCarNo + "开始保存:" + DateTime.Now.ToLongTimeString());
  311. btnSave.PerformClick();
  312. }
  313. }
  314. }
  315. #endregion
  316. //计量完成后进行语音播报,提示离开秤台,播报5次
  317. if (isMeasureSuccess)
  318. {
  319. if (voiceNum < AppConfigCache.voiceNum)
  320. {
  321. if (CacleCls.voiceOver)
  322. {
  323. vicPlayClass.GetVoicePlay("计量完成,请离开秤台", CacleCls.lockCarNo);
  324. voiceNum++;
  325. }
  326. }
  327. return;
  328. }
  329. }
  330. else
  331. {
  332. voiceNum = 0;
  333. isMeasureSuccess = false;
  334. lockWgtImg = CacleCls.weight;
  335. getFirst = false;
  336. getPreInfo = false;
  337. flagCaption = false;
  338. isVoiceDownCar = false;
  339. strGuid = "";
  340. if (!CacleCls.isClear)
  341. {
  342. CacleCls.Clear(); //清理一次数据
  343. btnSave.Enabled = false;
  344. cbCarNo.Text = "";
  345. cbCarNo.SelectedIndex = -1;
  346. txtCarNo.Text = "";
  347. txtMATTER_NAME.Text = "";
  348. txtFORWARDING_UNIT_NAME.Text = "";
  349. txtRECEIVING_UINT_NAME.Text = "";
  350. txtMETER_TYPE.Text = "";
  351. cbCarNo.Enabled = true;
  352. txtCarNo.Enabled = true;
  353. txtGroess.Text = "";
  354. txtTare.Text = "";
  355. txtNet.Text = "";
  356. //释放一次内存
  357. FlushMemory();
  358. }
  359. //避免海康截图完成时间在下磅后,所以压缩图片在下磅后5秒继续执行,超过这个时间则认为没有图片需压缩了
  360. if (iImgCnt < 10)
  361. {
  362. iImgCnt++;//最多在车辆下磅后,5秒内继续压缩下图片,如果都下磅5秒了还没图片说明没有图片需压缩了
  363. imgControl.ZipFiles();
  364. }
  365. }
  366. }));
  367. Thread.Sleep(500);
  368. }
  369. }, _cts.Token);
  370. }
  371. string dbFile = Path.Combine(AppConfigCache.path, "data/rfidDb.data");
  372. /// <summary>
  373. /// ping服务器
  374. /// </summary>
  375. private void TaskPing()
  376. {
  377. _cts2 = new CancellationTokenSource();
  378. Task.Run(() => {
  379. while (!_cts2.IsCancellationRequested)
  380. {
  381. try
  382. {
  383. Ping pingSend = new Ping();
  384. PingReply reply = pingSend.Send(AppConfigCache.ServiceIp, 1000);
  385. if (reply.Status == IPStatus.Success)
  386. CacleCls.serverFlag = true;
  387. else
  388. CacleCls.serverFlag = false;
  389. }
  390. catch (Exception)
  391. {
  392. CacleCls.serverFlag = false;
  393. }
  394. finally
  395. {
  396. if (CacleCls.serverFlag)
  397. {
  398. if (CacleCls.weight < 500 && DateTime.Now > CacleCls.updateRfidInfoTime)
  399. {
  400. CacleCls.updateRfidInfoTime.Value.AddHours(1); //每隔一小时更新一次rfid数据
  401. Dictionary<string, string> rfidInfo = new Dictionary<string, string>();
  402. RESTfulResult<List<MeterBaseRfidInfo>> rfids = rfidServer.doQueryRfid(new MeterBaseRfidInfo { valueFlag = "0" });
  403. if (rfids.Succeed)
  404. {
  405. if (rfids.Data != null && rfids.Data.Count > 0)
  406. {
  407. StringBuilder sb = new StringBuilder();
  408. foreach (MeterBaseRfidInfo rfid in rfids.Data)
  409. {
  410. try
  411. {
  412. sb.AppendLine($"{rfid.rfidCode},{rfid.carNo}");
  413. rfidInfo.Add(rfid.rfidCode, rfid.carNo);
  414. }
  415. catch { }
  416. }
  417. try
  418. {
  419. //如果目标文件存在则覆盖,不存在则创建
  420. File.WriteAllText(dbFile, sb.ToString());
  421. }
  422. catch(Exception ex)
  423. {
  424. lg.WriteLog(LogType.SystemLog, "写入rfid数据到本地失败:" + ex.Message);
  425. }
  426. CacleCls.rifdInfo = rfidInfo;
  427. }
  428. }
  429. else
  430. {
  431. lg.WriteLog(LogType.serverLog, $"获取RFID信息失败:{rfids.Message}");
  432. }
  433. }
  434. }
  435. else
  436. {
  437. if (CacleCls.rifdInfo == null || CacleCls.rifdInfo.Count == 0)
  438. {
  439. //读取本地rfid数据文件
  440. try
  441. {
  442. if (File.Exists(dbFile))
  443. {
  444. Dictionary<string, string> rfidInfo = new Dictionary<string, string>();
  445. string[] strs = File.ReadAllLines(dbFile);
  446. foreach (string str in strs)
  447. {
  448. try
  449. {
  450. string[] strInfo = str.Split(',');
  451. if (strInfo.Length == 2)
  452. {
  453. rfidInfo.Add(strInfo[0], strInfo[1]);
  454. }
  455. } catch { }
  456. }
  457. CacleCls.rifdInfo = rfidInfo;
  458. }
  459. }
  460. catch (Exception ex)
  461. {
  462. lg.WriteLog(LogType.WriteDbLog, "写入信息失败:" + ex.Message);
  463. }
  464. }
  465. }
  466. }
  467. Thread.Sleep(500);
  468. }
  469. }, _cts2.Token);
  470. }
  471. /// <summary>
  472. /// 结净数据上传服务
  473. /// 这里需等重量小于500且网络正常时触发
  474. /// 因为假如网络正常且重量大于500的时候,会优先将当前计量的数据存储到服务器上,然后返回结果进行打印操作
  475. /// 所以这里为了避免重复数据插入,所以需重量小于500且网络正常
  476. /// </summary>
  477. private void TaskDbUpload()
  478. {
  479. Dictionary<string, string> dic = new Dictionary<string, string>();
  480. _dbCts = new CancellationTokenSource();
  481. Task.Run(() =>
  482. {
  483. while (!_cts2.IsCancellationRequested)
  484. {
  485. try
  486. {
  487. if (CacleCls.weight < 500 && CacleCls.serverFlag)
  488. {
  489. dic.Clear();
  490. //检索本地实时库中结净数据。(若本地数据结净后,一次数据得删除,而结净数据中会保留一次数据的编号、重量、计量时间、计量点信息)
  491. //若本地存在结净数据未进行上传的,则进行数据上传并得到返回的结果:老一次计量编号|一次计量编号,老二次计量编号|新二次计量编号
  492. //得到结果后构造成Dictionary然后进行图片操作,修改图片名称及位置
  493. bool bReadFlag = false;
  494. string strRtMsgInfo = "";
  495. List<MeterWorkCarActualFirst> lm = FileOption.ReadDb(ref bReadFlag, ref strRtMsgInfo);
  496. if (bReadFlag)
  497. {
  498. //进行结净
  499. RESTfulResult<List<DjPbModel>> rmRst = workCarActualFirstService.doDbUpload(lm);
  500. if (rmRst.Succeed)
  501. {
  502. if (rmRst.Data.Count == lm.Count)
  503. {
  504. //直接重写文件
  505. FileOption.clearFile();
  506. //然后对图片进行压缩及修改名称处理
  507. foreach (DjPbModel dm in rmRst.Data)
  508. {
  509. dic.Add(dm.key, dm.value);
  510. }
  511. }
  512. else
  513. {
  514. //清理下文件
  515. FileOption.clearFile();
  516. //重写下未成功的数据
  517. foreach (MeterWorkCarActualFirst first in lm)
  518. {
  519. DjPbModel pm = rmRst.Data.Where(s => s.key == first.actualFirstNo).FirstOrDefault();
  520. if (pm == null || string.IsNullOrEmpty(pm.key) || string.IsNullOrEmpty(pm.value))
  521. {
  522. //Thread.Sleep(100);
  523. bool flag = FileOption.WriterDb(new ActualFirstModel { actualFirstNo = first.actualFirstNo, baseSpotNo = first.baseSpotNo, baseSpotName = first.baseSpotName, carNo = first.carNo, createTime = first.createTime, meterWeight = first.meterWeight }, out string msgInfo);
  524. if (!flag)
  525. {
  526. lg.WriteLog(LogType.serverLog, $"重写失败:{msgInfo},数据:actualFirstNo{first.actualFirstNo},baseSpotNo:{first.baseSpotNo},baseSpotName:{first.baseSpotName},carNo:{first.carNo},createTime:{first.createTime},meterWeight:{first.meterWeight}");
  527. }
  528. }
  529. else
  530. {
  531. dic.Add(pm.key, pm.value);
  532. }
  533. }
  534. }
  535. if (dic.Count > 0) imgControl.ZipFiles(dic);
  536. }
  537. else
  538. {
  539. //计量失败,播报失败,然后写led屏幕及日志
  540. led_controler.setStaticLineMsg(AppConfigCache.ledIp, "计量失败,请联系管理员");
  541. txtMsgInfo.Text = "计量失败:" + rmRst.ResultMessage;
  542. lg.WriteLog(LogType.serverLog, rmRst.ResultMessage);
  543. CacleCls.isLock = false;
  544. return;
  545. }
  546. }
  547. }
  548. }
  549. catch (Exception)
  550. {
  551. CacleCls.serverFlag = false;
  552. }
  553. Thread.Sleep(1000);
  554. }
  555. }, _dbCts.Token);
  556. }
  557. int lockWgtImg = 0;
  558. string strGuid = "";
  559. private void btnSave_Click(object sender, EventArgs e)
  560. {
  561. #region 下面是业务逻辑代码
  562. string msgInfo = "";
  563. if (txtCarNo.Focused) return; //如果正在修改车号,就必须等光标离开后再保存,否则容易导致车号输入了一半保存了
  564. if (CacleCls.isWd != 0) return;
  565. ucWeightT1.setStable(true); // 重量稳定
  566. ucWeightT1.setWgt(Math.Round((double)CacleCls.weight / 1000, 2)); // 最新重量
  567. CacleCls.lockWgt = CacleCls.weight;
  568. if (!CacleCls.lockWgt.ToString().EndsWith("0")) //个位不是0则说明超量程了
  569. {
  570. //txtMsgInfo.Text = "仪表重量[" + CacleCls.lockWgt + "]不是以0结尾,禁止计量操作!";
  571. vicPlayClass.GetVoicePlay("已超量程", CacleCls.lockCarNo);
  572. txtMsgInfo.Text = "当前重量已超量程,秤体量程为【" + AppConfigCache.maxRange + "】T,不允许进行自助计量操作!";
  573. return;
  574. }
  575. //接管状态点的保存
  576. if (CacleCls.isJg)
  577. {
  578. if (string.IsNullOrEmpty(CacleCls.lockCarNo))
  579. {
  580. txtMsgInfo.Text = "没有车号,无法保存";
  581. return;
  582. }
  583. else if (CacleCls.lockWgt < 500)
  584. {
  585. txtMsgInfo.Text = "重量过小,无法保存";
  586. return;
  587. }
  588. else if (CacleCls.isWd != 0)
  589. {
  590. txtMsgInfo.Text = "重量不稳定,无法保存";
  591. return;
  592. }
  593. else if (CacleCls.leftGs == "1" || CacleCls.rightGs == "1" || CacleCls.topJg == "1" || CacleCls.bottomJg == "1")
  594. {
  595. txtMsgInfo.Text = "激光被遮挡,车辆未停到位,无法保存";
  596. return;
  597. }
  598. else
  599. {
  600. lg.WriteLog(LogType.SystemLog, CacleCls.lockCarNo + "接管状态下进行的保存:" + DateTime.Now.ToLongTimeString());
  601. }
  602. }
  603. //存在零点,且不为接管状态则禁止计量
  604. if (CacleCls.isZeroState && !CacleCls.isJg)
  605. {
  606. vicPlayClass.GetVoicePlay("仪表未归零,无法计量,请联系大厅", CacleCls.lockCarNo);
  607. txtMsgInfo.Text = "仪表未归零,无法计量,请联系大厅"; //btnSave_Click
  608. led_controler.setStaticLineMsg(AppConfigCache.ledIp, "仪表未归零,无法计量");
  609. return;
  610. }
  611. if (!CacleCls.isJg && CacleCls.firstDb != null)
  612. {
  613. if (Math.Abs(CacleCls.firstDb.meterWeight.Value - CacleCls.lockWgt) < AppConfigCache.differenceWgt)
  614. {
  615. vicPlayClass.GetVoicePlay("计量失败,洁净重量过小,请联系计量大厅", CacleCls.lockCarNo);
  616. txtMsgInfo.Text = "计量失败,洁净重量过小";
  617. led_controler.setStaticLineMsg(AppConfigCache.ledIp, "计量失败,洁净重量过小");
  618. return;
  619. }
  620. }
  621. txtMsgInfo.Text = "称重保存中......";
  622. CacleCls.isLock = true;
  623. cbCarNo.Enabled = false;
  624. txtCarNo.Enabled = false;
  625. strGuid = strGuid == "" ? Guid.NewGuid().ToString() : strGuid;
  626. #region 截图
  627. if (!flagCaption)
  628. {
  629. for (int i = 0; i < lc.Count(); i++)
  630. {
  631. if (i == 0)
  632. {
  633. carCls.CapturePictrue2($"{AppConfigCache.path}/imgShort/formalImg/{AppConfigCache.pointNo}_C{strGuid}_tempImg_{i + 2}.jpg");
  634. continue;
  635. }
  636. //从_2开始,因为_1是仪表图片 2是车号快照抓拍
  637. ce.CapPic((uint)lc[i], $"{AppConfigCache.path}/imgShort/formalImg/{AppConfigCache.pointNo}_C{strGuid}_tempImg_{i + 2}.jpg");
  638. }
  639. flagCaption = true;
  640. }
  641. if (lockWgtImg != CacleCls.lockWgt)
  642. {
  643. lockWgtImg = CacleCls.lockWgt;
  644. foreach (Control cn in panel1.Controls)
  645. {
  646. if (cn.Name.Substring(cn.Name.Length - 1) == $"{AppConfigCache.channel}")
  647. {
  648. if (cn is PictureBox)
  649. {
  650. Bitmap bit = new Bitmap(cn.Width, cn.Height);//实例化一个和窗体一样大的bitmap
  651. Graphics g = Graphics.FromImage(bit);
  652. g.CompositingQuality = CompositingQuality.HighQuality;//质量设为最高 HighQuality
  653. g.CopyFromScreen(panel1.Left, panel1.Top + 25, 0, 0, new Size(cn.Width, cn.Height));//保存整个窗体为图片
  654. bit.Save($"{AppConfigCache.path}/imgShort/formalImg/{AppConfigCache.pointNo}_C{strGuid}_tempImg_1.jpg");//默认保存格式为PNG,保存成jpg格式质量不是很好
  655. bit.Dispose();
  656. break;
  657. }
  658. }
  659. }
  660. #region
  661. /* //下面的代码可实现抓放大的图,不过我这为了时间更准,抓的左侧显示的图
  662. if (iPic != 0)
  663. {
  664. ce.StopRealPlay(iPic);
  665. }
  666. ce.RealPlay(pictureShow, AppConfigCache.channel);
  667. plImgShow.Visible = true;
  668. Thread.Sleep(200);
  669. Bitmap bit = new Bitmap(plImgShow.Width, plImgShow.Height);//实例化一个和窗体一样大的bitmap
  670. Graphics g = Graphics.FromImage(bit);
  671. g.CompositingQuality = CompositingQuality.HighQuality;//质量设为最高 HighQuality
  672. g.CopyFromScreen(plImgShow.Left, plImgShow.Top + 25, 0, 0, new Size(plImgShow.Width, plImgShow.Height));//保存整个窗体为图片
  673. bit.Save($"{AppConfigCache.path}/imgShort/formalImg/{AppConfigCache.pointNo}_C{strGuid}_tempImg_1.jpg");//默认保存格式为PNG,保存成jpg格式质量不是很好
  674. bit.Dispose();
  675. plImgShow.Visible = false;
  676. ce.StopRealPlay(AppConfigCache.channel);
  677. //*/
  678. #endregion
  679. }
  680. #endregion
  681. if (CacleCls.serverFlag) //网络正常
  682. {
  683. //没有接管的情况下
  684. if (!CacleCls.isJg && CacleCls.firstDb != null && Math.Abs(CacleCls.firstDb.meterWeight.Value - AppConfigCache.differenceWgt) < AppConfigCache.differenceWgt)
  685. {
  686. string str = "第一次计量重量【" + CacleCls.firstDb.meterWeight.Value / 1000 + "T】和第二次计量重量【" + CacleCls.lockWgt / 1000 + "T】接近,小于结净最小值【" + AppConfigCache.differenceWgt / 1000 + " T】";
  687. led_controler.setStaticLineMsg(AppConfigCache.ledIp, "计量失败,请联系管理员");
  688. txtMsgInfo.Text = str;
  689. lg.WriteLog(LogType.serverLog, str);
  690. CacleCls.isLock = false;
  691. return;
  692. }
  693. //一次计量
  694. if (CacleCls.firstDb == null)
  695. {
  696. //进行计量,不管有没有一次计量数据,都调用这个,如果服务端判断有一次计量数据则进行结净,没有则做一次计量操作
  697. RESTfulResult<MeterWorkCarActualFirst> rmRst = workCarActualFirstService.doAddFirstDjDb(CacleCls.preTrackScale, new MeterWorkCarActualFirst
  698. {
  699. baseSpotNo = AppConfigCache.pointNo,
  700. baseSpotName = AppConfigCache.pointName,
  701. carNo = CacleCls.lockCarNo,
  702. createTime = DateTime.Now,
  703. meterWeight = CacleCls.lockWgt,
  704. createManNo = "system",
  705. createManName = "system",
  706. valueFlag = "1",
  707. meterMode = "2",
  708. isPreScale = "0",
  709. dataSource = "1",
  710. checkFlag = "1"
  711. });
  712. if (rmRst.Succeed)
  713. {
  714. isMeasureSuccess = true;
  715. CacleCls.actualNo = rmRst.Data?.actualFirstNo;
  716. CacleCls.tempNo = strGuid;
  717. }
  718. else
  719. {
  720. //计量失败,播报失败,然后写led屏幕及日志
  721. led_controler.setStaticLineMsg(AppConfigCache.ledIp, "计量失败,请联系管理员");
  722. txtMsgInfo.Text = "计量失败:" + rmRst.ResultMessage;
  723. lg.WriteLog(LogType.serverLog, rmRst.ResultMessage);
  724. CacleCls.isLock = false;
  725. return;
  726. }
  727. }
  728. else //结净操作
  729. {
  730. RESTfulResult<string> rmRst = workCarActualFirstService.doAddNet(CacleCls.preTrackScale, CacleCls.firstDb, new MeterWorkCarActualFirst
  731. {
  732. baseSpotNo = AppConfigCache.pointNo,
  733. baseSpotName = AppConfigCache.pointName,
  734. carNo = CacleCls.lockCarNo,
  735. createTime = DateTime.Now,
  736. meterWeight = CacleCls.lockWgt,
  737. createManNo = "system",
  738. createManName = "system",
  739. valueFlag = "1",
  740. meterMode = "2",
  741. isPreScale = "0",
  742. dataSource = "1",
  743. checkFlag = "1"
  744. });
  745. if (rmRst.Succeed)
  746. {
  747. isMeasureSuccess = true;
  748. CacleCls.actualNo = rmRst.Data;
  749. CacleCls.tempNo = strGuid;
  750. }
  751. else
  752. {
  753. //计量失败,播报失败,然后写led屏幕及日志
  754. led_controler.setStaticLineMsg(AppConfigCache.ledIp, "计量失败,请联系管理员");
  755. txtMsgInfo.Text = "计量失败:" + rmRst.ResultMessage;
  756. lg.WriteLog(LogType.serverLog, rmRst.ResultMessage);
  757. CacleCls.isLock = false;
  758. return;
  759. }
  760. }
  761. }
  762. else
  763. {
  764. //写本地文件
  765. bool flag = FileOption.WriterDb(new ActualFirstModel { actualFirstNo = strGuid, baseSpotNo = AppConfigCache.pointNo, baseSpotName = AppConfigCache.pointName, carNo = CacleCls.lockCarNo, createTime = DateTime.Now, meterWeight = CacleCls.lockWgt },out msgInfo);
  766. if (flag)
  767. {
  768. isMeasureSuccess = true;
  769. }
  770. else
  771. {
  772. led_controler.setStaticLineMsg(AppConfigCache.ledIp, "计量失败,请联系管理员");
  773. txtMsgInfo.Text = "计量失败:" + msgInfo;
  774. lg.WriteLog(LogType.serverLog, msgInfo);
  775. CacleCls.isLock = false;
  776. return;
  777. }
  778. }
  779. //计量成功
  780. if (isMeasureSuccess)
  781. {
  782. #region 毛皮净赋值
  783. if (CacleCls.firstDb != null && CacleCls.firstDb.meterWeight > 0 && CacleCls.lockWgt > 0)
  784. {
  785. if (CacleCls.firstDb.meterWeight > CacleCls.lockWgt)
  786. {
  787. txtGroess.Text = $"{CacleCls.firstDb.meterWeight / 1000}";
  788. txtTare.Text = $"{CacleCls.lockWgt / 1000}";
  789. txtNet.Text = $"{(CacleCls.firstDb.meterWeight - CacleCls.lockWgt) / 1000}";
  790. }
  791. else
  792. {
  793. txtGroess.Text = $"{CacleCls.lockWgt / 1000}";
  794. txtTare.Text = $"{CacleCls.firstDb.meterWeight / 1000}";
  795. txtNet.Text = $"{(CacleCls.lockWgt - CacleCls.firstDb.meterWeight) / 1000}";
  796. }
  797. }
  798. if (!string.IsNullOrEmpty(CacleCls.LEDResultMessage))
  799. {
  800. led_controler.setStaticLineMsg(AppConfigCache.ledIp, CacleCls.LEDResultMessage);
  801. }
  802. #endregion
  803. //屏幕截图操作
  804. _ = BeginInvoke(new Action(() => { shotImageScreen(strGuid); }));
  805. }
  806. #endregion
  807. }
  808. private void btnOpenVoice_Click(object sender, EventArgs e)
  809. {
  810. //*
  811. if (btnOpenVoice.Text == "打开对讲")
  812. {
  813. VoiceOpen();
  814. }
  815. else
  816. {
  817. VoiceClose();
  818. }
  819. //*/
  820. }
  821. private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
  822. {
  823. try { mx.ClosingCollect(); } catch { }
  824. try { rfid.ClosingCollect(); } catch { }
  825. try { if (bVoice) ce.StopTalk(); } catch { }
  826. foreach (int i in voPlay)
  827. {
  828. try { ce.StopRealPlay(i); } catch { }
  829. }
  830. try { plc.Stop(); } catch { }
  831. try { _cts?.Cancel(); } catch { }
  832. try { _cts2?.Cancel(); } catch { }
  833. try { _dbCts?.Cancel(); } catch { }
  834. try { carCls?.LoginOut(); } catch { }
  835. //try { carCls2?.LoginOut(); } catch { }
  836. try { imgControl.Stop(); } catch { }
  837. }
  838. /// <summary>
  839. /// 必须先打开视频,然后再打开语音
  840. /// </summary>
  841. private void VoiceOpen()
  842. {
  843. try
  844. {
  845. if (ce.StartTalk())
  846. {
  847. btnOpenVoice.Text = "关闭对讲";
  848. bVoice = true;
  849. }
  850. }
  851. catch (Exception ex)
  852. {
  853. txtMsgInfo.Text = "打开对讲失败:" + ex.Message;
  854. }
  855. }
  856. /// <summary>
  857. /// 关闭语音对讲
  858. /// </summary>
  859. private void VoiceClose()
  860. {
  861. try
  862. {
  863. if (ce.StopTalk())
  864. {
  865. btnOpenVoice.Text = "打开对讲";
  866. bVoice = false;
  867. }
  868. }
  869. catch (Exception ex)
  870. {
  871. txtMsgInfo.Text = "关闭对讲失败:" + ex.Message;
  872. }
  873. }
  874. private void btnExport_Click(object sender, EventArgs e)
  875. {
  876. ClsControlPack.ExportDataWithSaveDialog2(ref ultraGridFirst, DateTime.Now.ToString("yyyyMMddHHmmss"));
  877. }
  878. private void cbCarNo_SelectedIndexChanged(object sender, EventArgs e)
  879. {
  880. CacleCls.isLock = false;
  881. }
  882. private void cbJg_CheckedChanged(object sender, EventArgs e)
  883. {
  884. CacleCls.isJg = cbJg.Checked;
  885. btnSave.Enabled = cbJg.Checked;
  886. }
  887. private void txtCarNo_TextChanged(object sender, EventArgs e)
  888. {
  889. CacleCls.isLock = false;
  890. }
  891. private void PictureBoxDoubleClick(object sender, EventArgs e)
  892. {
  893. if (iPic != 0)
  894. {
  895. ce.StopRealPlay(iPic);
  896. }
  897. PictureBox picture = (PictureBox)sender;
  898. iPic = Convert.ToInt32(picture.Name.Substring(picture.Name.Length - 1, 1));
  899. plImgShow.Visible = true;
  900. ce.RealPlay(pictureShow, iPic);
  901. }
  902. private void pictureShow_DoubleClick(object sender, EventArgs e)
  903. {
  904. plImgShow.Visible = false;
  905. ce.StopRealPlay(iPic);
  906. iPic = 0;
  907. }
  908. private void timer1_Tick(object sender, EventArgs e)
  909. {
  910. if (!string.IsNullOrEmpty(CacleCls.voicCarNo))
  911. {
  912. txtMsgInfo.Text += CacleCls.voicCarNo + "\n\r";
  913. }
  914. CacleCls.voicCarNo = "";
  915. if(!string.IsNullOrEmpty(CacleCls.rfidCarNo))
  916. txtMsgInfo.Text += CacleCls.rfidCarNo + "\n\r";
  917. //*/
  918. }
  919. /// <summary>
  920. /// 终端截图(临时截图,使用临时ID存储)
  921. /// </summary>
  922. public void shotImageScreen(string strActualFirstNo)
  923. {
  924. try
  925. {
  926. #region 截取图片信息
  927. //截取屏幕信息
  928. Point screenPoint = plCaptionMain.PointToScreen(new Point());
  929. Rectangle rect = new Rectangle(screenPoint, plCaptionMain.Size);
  930. Image img = new Bitmap(plCaptionMain.Width, plCaptionMain.Height);
  931. Graphics g = Graphics.FromImage(img);
  932. g.CopyFromScreen(rect.X - 1, rect.Y - 1, 0, 0, rect.Size);//"D://file/1.jpg"
  933. img.Save(string.Format("{0}imgShort\\formalImg\\{1}_{2}_{3}.jpg",
  934. AppDomain.CurrentDomain.SetupInformation.ApplicationBase,
  935. AppConfigCache.pointNo, "C" + strActualFirstNo, 7), System.Drawing.Imaging.ImageFormat.Jpeg);
  936. //lg.WriteLog(35, "完成截图 成功标识:" + PbCache.shotSuccess.ToString() + "车号:" + PbCache.lockCarNo + ";重量:" + PbCache.lockWgt + ";时间:" + DateTime.Now.ToLongTimeString());
  937. #endregion 截取图片信息
  938. }
  939. catch (Exception ex)
  940. {
  941. lg.WriteLog(LogType.SystemLog, "计量完成,但图片截取失败,编号:" + strActualFirstNo);
  942. }
  943. }
  944. #region 释放内存
  945. [DllImport("kernel32.dll")]
  946. private static extern bool SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize);
  947. //刷新存储器
  948. private static void FlushMemory()
  949. {
  950. GC.Collect();
  951. GC.WaitForPendingFinalizers();
  952. if (Environment.OSVersion.Platform == PlatformID.Win32NT)
  953. {
  954. SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1);
  955. }
  956. }
  957. #endregion
  958. }
  959. }