Main.cs 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636
  1. using Microsoft.Office.Interop.Excel;
  2. using System;
  3. using System.Collections.Concurrent;
  4. using System.Collections.Generic;
  5. using System.ComponentModel;
  6. using System.Data;
  7. using System.Drawing;
  8. using System.Globalization;
  9. using System.IO;
  10. using System.IO.Compression;
  11. using System.Linq;
  12. using System.Media;
  13. using System.Net;
  14. using System.Runtime.InteropServices;
  15. using System.Security.Principal;
  16. using System.Text;
  17. using System.Text.RegularExpressions;
  18. using System.Threading;
  19. using System.Threading.Tasks;
  20. using System.Windows.Forms;
  21. using UAS_Tools_HY;
  22. using UAS_Tools_HY.Properties;
  23. using UAS_Tools_HY.PublicMethods;
  24. using Action = System.Action;
  25. using Application = Microsoft.Office.Interop.Excel.Application;
  26. using DataTable = System.Data.DataTable;
  27. using Timer = System.Windows.Forms.Timer;
  28. namespace UAS_MES_Tools
  29. {
  30. public partial class Main : Form
  31. {
  32. string _Account, _Password, _UserName;
  33. DataTable dt;
  34. Timer loadTime;
  35. string minTime, maxTime;
  36. string curRuleId, curRule, curRuleLeng;
  37. int ishaveInd;
  38. Timer File_timer;
  39. Timer File_timer1;
  40. string saveFiles;
  41. int currentNum = 1;
  42. private CancellationTokenSource _currentOperationCts;
  43. public Main(string account, string password)
  44. {
  45. _Account = account;
  46. _Password = password;
  47. InitializeComponent();
  48. }
  49. private void Main_Load(object sender, EventArgs e)
  50. {
  51. currUser.Text = "当前账户: " + _Account;
  52. dt = ConnectDB.ExecuteSelect($"select * from employee where em_code = '{_Account}'");
  53. if (dt.Rows.Count > 0)
  54. {
  55. _UserName = dt.Rows[0]["em_name"].ToString();
  56. }
  57. loadTime_Tick(null, null);
  58. loadTime = new Timer();
  59. loadTime.Interval = 1000;
  60. loadTime.Tick += loadTime_Tick;
  61. loadTime.Start();
  62. SN.SelectAll();
  63. SN.Focus();
  64. settingLeftInput1.Text = BaseUtil.GetCacheData("SettingCount").ToString();
  65. settingLeftInput2.Text = BaseUtil.GetCacheData("SettingVolume").ToString();
  66. if (string.IsNullOrEmpty(BaseUtil.GetCacheData("SettingVolume").ToString())) dSum.Text = "0";
  67. else dSum.Text = BaseUtil.GetCacheData("SettingVolume").ToString();
  68. settingRightInput1.Text = BaseUtil.GetCacheData("SettingNGPath").ToString();
  69. settingRightInput2.Text = BaseUtil.GetCacheData("SettingExportPath").ToString();
  70. QDcheckbox1.Checked = true;
  71. QDdtp2.Value = QDdtp1.Value.AddDays(1);
  72. rulesQuery_Click(null, null);
  73. QDquery_Click(null, null);
  74. saveFiles = Path.Combine(Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).FullName, $"FtpFiles");
  75. if (!Directory.Exists(saveFiles))
  76. {
  77. Directory.CreateDirectory(saveFiles);
  78. }
  79. //saveFiles = Path.Combine(saveFiles, DateTime.Now.ToString("yyyyMMdd"));
  80. //if (!Directory.Exists(saveFiles))
  81. //{
  82. // Directory.CreateDirectory(saveFiles);
  83. //}
  84. File_timer = new Timer();
  85. File_timer.Interval = 30 * 1000;
  86. File_timer.Tick += Timer_Tick;
  87. timerVal.Text = "30";
  88. FileCountVal.Text = "10";
  89. FtpPathVal.Text = "ftp://10.18.13.48:21";
  90. handExeVal.Text = "120";
  91. File_timer1 = new Timer();
  92. File_timer1.Interval = Convert.ToInt32(handExeVal.Text) * 1000;
  93. File_timer1.Tick += FileTimer_Tick;
  94. }
  95. private void SN_KeyDown(object sender, KeyEventArgs e)
  96. {
  97. if (e.KeyCode != Keys.Enter) return;
  98. if(checkPagination.SelectedIndex != 0) checkPagination.SelectedIndex = 0;
  99. if (CheckEnter()) return;
  100. bool checkRes = true;
  101. if (radio1.Checked)
  102. {
  103. dt = ConnectDB.ExecuteSelect($@"SELECT COUNT(1) sum FROM dcrlogexcel WHERE item = '{SN.Text.Trim()}'");
  104. if (dt.Rows[0]["sum"].ToString() == "0")
  105. {
  106. PlaySound("NG");
  107. MessageBox.Show($"{SN.Text.Trim()},没有DCR测试数据", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  108. checkRes = false;
  109. return;
  110. }
  111. }
  112. if (FormMethods.IsCheckSNRules(curRule, SN.Text.Trim(), curRuleLeng))
  113. {
  114. PlaySound("NG");
  115. MessageBox.Show($"{SN.Text.Trim()},不符合条码规则", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  116. checkRes = false;
  117. return;
  118. }
  119. dt = ConnectDB.ExecuteSelect($@"select * from g_packing_sncheck where sn = '{SN.Text.Trim()}'");
  120. if (dt.Rows.Count > 0)
  121. {
  122. PlaySound("NG");
  123. MessageBox.Show($"{SN.Text.Trim()},历史记录中已核对", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  124. checkRes = false;
  125. return;
  126. }
  127. ishaveInd = -1;
  128. if (Datas.Rows.Count > 0)
  129. {
  130. foreach (DataGridViewRow item in Datas.Rows)
  131. {
  132. if (SN.Text.Trim() == item.Cells[0].Value.ToString())
  133. {
  134. ishaveInd = Datas.Rows.IndexOf(item);
  135. }
  136. }
  137. }
  138. if (ishaveInd >= 0)
  139. {
  140. PlaySound("NG");
  141. MessageBox.Show($"{SN.Text.Trim()},已核对装箱", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  142. checkRes = false;
  143. return;
  144. /*int iCou = Convert.ToInt32(Datas.Rows[ishaveInd].Cells[2].Value);
  145. iCou += 1;
  146. Datas.Rows[ishaveInd].Cells[3].Value = currTime.Text;
  147. Datas.Rows[ishaveInd].Cells[6].Value = checkRes ? "OK" : "NG";
  148. PlaySound("OK");*/
  149. }
  150. else
  151. {
  152. DataGridViewRow row = new DataGridViewRow();
  153. row.CreateCells(Datas);
  154. row.Cells[0].Value = SN.Text.Trim();
  155. row.Cells[1].Value = BoxNo.Text.Trim();
  156. row.Cells[2].Value = 1;
  157. row.Cells[3].Value = currTime.Text;
  158. row.Cells[4].Value = _UserName;
  159. row.Cells[5].Value = radio1.Checked ? "是" : "否";
  160. row.Cells[6].Value = checkRes ? "OK" : "NG";
  161. Datas.Rows.Add(row);
  162. PlaySound("OK");
  163. Datas.FirstDisplayedScrollingRowIndex = Datas.Rows.Count - 1;
  164. try
  165. {
  166. int typeNum = ChangeDetail(row);
  167. if (typeNum == 1)
  168. {
  169. SN.Focus();
  170. SN.SelectAll();
  171. SN.Text = "";
  172. }
  173. else if (typeNum == 2)
  174. {
  175. SN.Text = "";
  176. dCount.Text = "0";
  177. BoxNo.Enabled = true;
  178. BoxNo.Focus();
  179. BoxNo.SelectAll();
  180. //BoxNo.Text = "";
  181. //Datas.Rows.Clear();
  182. Application excelApp = null;
  183. Workbook workbook = null;
  184. Worksheet worksheet = null;
  185. Range range = null;
  186. string tempTemplatePath = null;
  187. try
  188. {
  189. string checkExportModel = Path.Combine(settingRightInput2.Text, BoxNo.Text.Trim() + ".xlsx");
  190. if (string.IsNullOrEmpty(settingRightInput2.Text) || !Directory.Exists(settingRightInput2.Text))
  191. {
  192. MessageBox.Show($"输出目录不存在: {settingRightInput2.Text}", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  193. return;
  194. }
  195. byte[] templateBytes = Resources.checkExportModel;
  196. if (templateBytes == null || templateBytes.Length == 0)
  197. {
  198. MessageBox.Show("未能加载模板文件", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  199. return;
  200. }
  201. tempTemplatePath = Path.GetTempFileName().Replace(".tmp", ".xlsx");
  202. File.WriteAllBytes(tempTemplatePath, templateBytes);
  203. excelApp = new Application();
  204. excelApp.Visible = false;
  205. excelApp.DisplayAlerts = false;
  206. workbook = excelApp.Workbooks.Open(tempTemplatePath);
  207. object sheetIndex = 1;
  208. worksheet = (Worksheet)workbook.Worksheets[sheetIndex];
  209. dt = ConnectDB.ExecuteSelect($@"select * from g_packing_sncheck where outbox_no = '{BoxNo.Text.Trim()}'");
  210. if (dt.Rows.Count > 0)
  211. {
  212. worksheet.Cells[1, 3] = DateTime.Now.ToString("yyyy-MM-dd");
  213. worksheet.Cells[1, 7] = BoxNo.Text.Trim();
  214. int startRow = 3;
  215. int startColumn = 2;
  216. int currInd = 0;
  217. int dataRowsCount = dt.Rows.Count;
  218. foreach (DataRow item in dt.Rows)
  219. {
  220. worksheet.Cells[startRow + currInd, startColumn - 1] = currInd + 1;
  221. worksheet.Cells[startRow + currInd, startColumn] = item["SN"].ToString();
  222. if (currInd > 23)
  223. {
  224. currInd = 0;
  225. startColumn += 2;
  226. }
  227. else
  228. {
  229. currInd += 1;
  230. }
  231. }
  232. int endRow = startRow + 25;
  233. range = worksheet.Range[worksheet.Cells[startRow, 1], worksheet.Cells[endRow, startColumn]];
  234. range.HorizontalAlignment = XlHAlign.xlHAlignCenter;
  235. range.VerticalAlignment = XlVAlign.xlVAlignCenter;
  236. }
  237. worksheet.Columns.AutoFit();
  238. workbook.SaveAs(
  239. Filename: checkExportModel,
  240. FileFormat: XlFileFormat.xlOpenXMLWorkbook,
  241. Password: Type.Missing,
  242. WriteResPassword: Type.Missing,
  243. ReadOnlyRecommended: Type.Missing,
  244. CreateBackup: Type.Missing,
  245. AccessMode: XlSaveAsAccessMode.xlExclusive,
  246. ConflictResolution: Type.Missing,
  247. AddToMru: false,
  248. TextCodepage: Type.Missing,
  249. TextVisualLayout: Type.Missing,
  250. Local: Type.Missing
  251. );
  252. MessageBox.Show($"Excel文件已成功导出到: {checkExportModel}", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
  253. }
  254. catch (Exception ex)
  255. {
  256. MessageBox.Show($"生成 Excel 文件时出错: {ex.Message}", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  257. }
  258. finally
  259. {
  260. // 正确释放COM对象
  261. if (worksheet != null)
  262. {
  263. try
  264. {
  265. Marshal.ReleaseComObject(worksheet);
  266. }
  267. catch { }
  268. worksheet = null;
  269. }
  270. if (workbook != null)
  271. {
  272. try
  273. {
  274. workbook.Close(false);
  275. Marshal.ReleaseComObject(workbook);
  276. }
  277. catch { }
  278. workbook = null;
  279. }
  280. if (excelApp != null)
  281. {
  282. try
  283. {
  284. excelApp.Quit();
  285. Marshal.ReleaseComObject(excelApp);
  286. }
  287. catch { }
  288. excelApp = null;
  289. }
  290. if (!string.IsNullOrEmpty(tempTemplatePath) && File.Exists(tempTemplatePath))
  291. {
  292. try
  293. {
  294. File.Delete(tempTemplatePath);
  295. }
  296. catch (Exception ex)
  297. {
  298. }
  299. }
  300. GC.Collect();
  301. GC.WaitForPendingFinalizers();
  302. }
  303. }
  304. QDquery_Click(null, null);
  305. if (Datas.Rows.Count == Convert.ToInt32(settingLeftInput1.Text))
  306. {
  307. Datas.Rows.Clear();
  308. }
  309. }
  310. catch (Exception ex)
  311. {
  312. MessageBox.Show(ex.Message, "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  313. return;
  314. }
  315. }
  316. }
  317. private int ChangeDetail(DataGridViewRow row)
  318. {
  319. int inputSum = Convert.ToInt32(dCount.Text);
  320. dCount.Text = (inputSum + 1).ToString();
  321. int insertCount = ConnectDB.ExecuteInsert($@"INSERT INTO g_packing_sncheck (work_order,part_no,sn,outbox_no,
  322. count,update_time,update_name,check_id,rule_name,rule_value,capacity,ISCHECHK_DCR,rule_id)
  323. VALUES ( '', '', '{row.Cells[0].Value}', '{row.Cells[1].Value}',
  324. '{row.Cells[2].Value}',sysdate,'{_UserName}',packcheckid_seq.NEXTVAL,'{dRules.Text.Trim()}','{curRule}','{dSum.Text}','{row.Cells[5].Value}','{curRuleId}' )");
  325. if (Convert.ToInt32(dCount.Text) < Convert.ToInt32(dSum.Text))
  326. {
  327. return 1;
  328. }
  329. else
  330. {
  331. return 2;
  332. }
  333. //if(Convert.ToInt32(dCount.Text) == Convert.ToInt32(dSum.Text))
  334. //{
  335. // foreach (DataGridViewRow item in Datas.Rows)
  336. // {
  337. // int insertCount = ConnectDB.ExecuteInsert($@"INSERT INTO g_packing_sncheck (work_order,part_no,sn,outbox_no,
  338. // count,update_time,update_name,check_id,rule_name,rule_value)
  339. // VALUES ( '', '', '{item.Cells[0].Value}', '{item.Cells[1].Value}',
  340. // '{item.Cells[2].Value}',sysdate,'{_UserName}',packcheckid_seq.NEXTVAL,'{dRules.Text.Trim()}','{curRule}' )");
  341. // }
  342. // return true;
  343. //}
  344. //else
  345. //{
  346. // return false;
  347. //}
  348. }
  349. private void BoxNo_Leave(object sender, EventArgs e)
  350. {
  351. if (!string.IsNullOrEmpty(BoxNo.Text))
  352. {
  353. KeyEventArgs KeyEventArg = new KeyEventArgs(Keys.Enter);
  354. BoxNo_KeyDown(null, KeyEventArg);
  355. }
  356. }
  357. private void BoxNo_KeyDown(object sender, KeyEventArgs e)
  358. {
  359. if (e.KeyCode != Keys.Enter) return;
  360. dt = ConnectDB.ExecuteSelect($@"SELECT * FROM g_packing_sncheck a,g_packing_rules b WHERE a.outbox_no = '{BoxNo.Text}' AND a.rule_id = b.rule_id");
  361. if (dt.Rows.Count > 0)
  362. {
  363. if (Convert.ToInt32(dt.Rows[0]["CAPACITY"].ToString()) > dt.Rows.Count)
  364. {
  365. dRules.Text = dt.Rows[0]["RULE_NAME"].ToString();
  366. curRule = dt.Rows[0]["RULE_VALUE"].ToString();
  367. curRuleId = dt.Rows[0]["RULE_ID"].ToString();
  368. curRuleLeng = dt.Rows[0]["RULE_LENGTH"].ToString();
  369. dRules.Enabled = false;
  370. radio1.Checked = dt.Rows[0]["ISCHECHK_DCR"].ToString() == "是" ? true : false;
  371. dCount.Text = dt.Rows.Count.ToString();
  372. settingLeftInput2.Text = dt.Rows[0]["CAPACITY"].ToString();
  373. dSum.Text = dt.Rows[0]["CAPACITY"].ToString();
  374. BaseUtil.SetCacheData("SettingVolume", dt.Rows[0]["CAPACITY"].ToString());
  375. Datas.Rows.Clear();
  376. foreach (DataRow item in dt.Rows)
  377. {
  378. DataGridViewRow row = new DataGridViewRow();
  379. row.CreateCells(Datas);
  380. row.Cells[0].Value = item["SN"].ToString();
  381. row.Cells[1].Value = item["OUTBOX_NO"].ToString();
  382. row.Cells[2].Value = item["COUNT"].ToString();
  383. row.Cells[3].Value = item["UPDATE_TIME"].ToString();
  384. row.Cells[4].Value = item["UPDATE_NAME"].ToString();
  385. row.Cells[5].Value = item["ISCHECHK_DCR"].ToString();
  386. row.Cells[6].Value = "OK";
  387. Datas.Rows.Add(row);
  388. }
  389. }
  390. else
  391. {
  392. BoxNo.Focus();
  393. BoxNo.SelectAll();
  394. MessageBox.Show($"核对完成,此箱{BoxNo.Text} 已装满{dt.Rows[0]["CAPACITY"].ToString()} 个,请扫描未核对箱号", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  395. BoxNo.Text = "";
  396. return;
  397. }
  398. }
  399. if (CheckEnter())
  400. {
  401. BoxNo.Text = "";
  402. return;
  403. }
  404. /*if (Datas.Rows.Count > 0)
  405. {
  406. foreach(DataGridViewRow item in Datas.Rows)
  407. {
  408. item.Cells[1].Value = BoxNo.Text.Trim();
  409. }
  410. }*/
  411. BoxNo.Enabled = false;
  412. SN.SelectAll();
  413. SN.Focus();
  414. }
  415. private bool CheckEnter()
  416. {
  417. if (string.IsNullOrEmpty(settingLeftInput1.Text))
  418. {
  419. MessageBox.Show("请维护列表记录数", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  420. return true;
  421. }
  422. if (string.IsNullOrEmpty(settingLeftInput2.Text))
  423. {
  424. MessageBox.Show("请维护箱内容量", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  425. return true;
  426. }
  427. if (!Regex.IsMatch(dSum.Text, @"^[1-9]\d*$"))
  428. {
  429. MessageBox.Show("箱内容量维护应为正整数", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  430. return true;
  431. }
  432. if (string.IsNullOrEmpty(dRules.Text))
  433. {
  434. MessageBox.Show("请选择条码规则", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  435. return true;
  436. }
  437. if (dRules.Enabled)
  438. {
  439. MessageBox.Show("请选择确认条码规则", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  440. return true;
  441. }
  442. return false;
  443. }
  444. private void settingLeftSubmit_Click(object sender, EventArgs e)
  445. {
  446. if (string.IsNullOrEmpty(settingLeftInput1.Text))
  447. {
  448. MessageBox.Show("请输入列表记录数", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  449. return;
  450. }
  451. if (string.IsNullOrEmpty(settingLeftInput2.Text))
  452. {
  453. MessageBox.Show("请输入箱内容量", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  454. return;
  455. }
  456. if (Convert.ToInt32(dCount.Text) > 0)
  457. {
  458. if(Convert.ToInt32(dSum.Text) > Convert.ToInt32(settingLeftInput2.Text))
  459. {
  460. MessageBox.Show($"已扫描{Convert.ToInt32(dCount.Text)} 个产品,修改箱容量需大于{Convert.ToInt32(settingLeftInput2.Text)} ", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  461. return;
  462. }
  463. }
  464. BaseUtil.SetCacheData("SettingCount", settingLeftInput1.Text);
  465. BaseUtil.SetCacheData("SettingVolume", settingLeftInput2.Text);
  466. dSum.Text = BaseUtil.GetCacheData("SettingVolume").ToString();
  467. MessageBox.Show("已提交扫描设置", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
  468. }
  469. private void settingRightSubmit_Click(object sender, EventArgs e)
  470. {
  471. if (string.IsNullOrEmpty(settingRightInput2.Text))
  472. {
  473. MessageBox.Show("请选择导出文件目录", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  474. return;
  475. }
  476. if(!string.IsNullOrEmpty(settingRightInput1.Text)) BaseUtil.SetCacheData("SettingNGPath", settingRightInput1.Text);
  477. BaseUtil.SetCacheData("SettingExportPath", settingRightInput2.Text);
  478. MessageBox.Show("已提交文件设置", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
  479. }
  480. private void QDquery_Click(object sender, EventArgs e)
  481. {
  482. StringBuilder filterStr = new StringBuilder();
  483. if (!string.IsNullOrEmpty(QDInput1.Text))
  484. {
  485. filterStr.Append($"WHERE instr(SN,'{QDInput1.Text}') > 0");
  486. }
  487. if (!string.IsNullOrEmpty(QDInput2.Text))
  488. {
  489. if (filterStr.Length == 0)
  490. {
  491. filterStr.Append($"WHERE instr(OUTBOX_NO,'{QDInput2.Text}') > 0");
  492. }
  493. else
  494. {
  495. filterStr.Append($" and instr(OUTBOX_NO, '{QDInput2.Text}') > 0");
  496. }
  497. }
  498. if (QDcheckbox1.Checked)
  499. {
  500. string dtp1 = QDdtp1.Value.ToString("yyyy-MM-dd 00:00:00");
  501. string dtp2 = QDdtp2.Value.ToString("yyyy-MM-dd 00:00:00");
  502. if (filterStr.Length == 0)
  503. {
  504. filterStr.Append($"WHERE update_time > TO_DATE('{dtp1}','YYYY-MM-DD HH24:MI:SS') AND update_time <= TO_DATE('{dtp2}','YYYY-MM-DD HH24:MI:SS')");
  505. }
  506. else
  507. {
  508. filterStr.Append($" AND update_time > TO_DATE('{dtp1}','YYYY-MM-DD HH24:MI:SS') AND update_time <= TO_DATE('{dtp2}','YYYY-MM-DD HH24:MI:SS')");
  509. }
  510. }
  511. if(sender == null)
  512. {
  513. Task.Run(() =>
  514. {
  515. dt = ConnectDB.ExecuteSelect($@"SELECT sn dqsn,outbox_no dqoutbox_no,count dqcount,
  516. update_time dqupdate_time,update_name dqname,rule_name dqrule_name,rule_value dqrule_value
  517. FROM g_packing_sncheck {filterStr.ToString()} ORDER BY update_time desc");
  518. this.Invoke(new Action(() =>
  519. {
  520. QDDatas.DataSource = dt;
  521. }));
  522. });
  523. }
  524. else
  525. {
  526. Loading LoadingForm = new Loading(filterStr.ToString());
  527. if (LoadingForm.ShowDialog() == DialogResult.OK)
  528. {
  529. DataTable dt = LoadingForm.ResultData;
  530. QDDatas.DataSource = dt;
  531. }
  532. }
  533. }
  534. private void QDexport_Click(object sender, EventArgs e)
  535. {
  536. if(QDDatas.Rows.Count == 0)
  537. {
  538. MessageBox.Show("请先查询出导出数据", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  539. return;
  540. }
  541. if (string.IsNullOrEmpty(settingRightInput2.Text))
  542. {
  543. MessageBox.Show("请先在设置中选择导出路径", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  544. return;
  545. }
  546. Application excelApp = null;
  547. Workbook workbook = null;
  548. Worksheet worksheet = null;
  549. Range range = null;
  550. string tempTemplatePath = null;
  551. try
  552. {
  553. string exportPath = Path.Combine(settingRightInput2.Text, DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ".xlsx");
  554. if (string.IsNullOrEmpty(settingRightInput2.Text) || !Directory.Exists(settingRightInput2.Text))
  555. {
  556. MessageBox.Show($"输出目录不存在: {settingRightInput2.Text}", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  557. return;
  558. }
  559. byte[] templateBytes = Resources.exportModel; // 假设Resources.exportModel是有效的资源
  560. if (templateBytes == null || templateBytes.Length == 0)
  561. {
  562. MessageBox.Show("未能加载模板文件", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  563. return;
  564. }
  565. tempTemplatePath = Path.GetTempFileName().Replace(".tmp", ".xlsx");
  566. File.WriteAllBytes(tempTemplatePath, templateBytes);
  567. excelApp = new Application();
  568. excelApp.Visible = false;
  569. excelApp.DisplayAlerts = false;
  570. workbook = excelApp.Workbooks.Open(tempTemplatePath);
  571. object sheetIndex = 1;
  572. worksheet = (Worksheet)workbook.Worksheets[sheetIndex];
  573. int startRow = 2;
  574. int dataRowsCount = QDDatas.Rows.Count;
  575. for (int i = 0; i < QDDatas.Rows.Count; i++)
  576. {
  577. worksheet.Cells[startRow + i, 1] = i + 1; // 改为从1开始编号,更符合Excel习惯
  578. worksheet.Cells[startRow + i, 2] = QDDatas.Rows[i].Cells[0].Value?.ToString();
  579. }
  580. int endRow = startRow + dataRowsCount - 1;
  581. range = worksheet.Range[worksheet.Cells[startRow, 1], worksheet.Cells[endRow, 2]];
  582. range.HorizontalAlignment = XlHAlign.xlHAlignCenter; // 水平居中
  583. range.VerticalAlignment = XlVAlign.xlVAlignCenter; // 垂直居中
  584. worksheet.Columns.AutoFit();
  585. // 修复SaveAs方法,使用正确的参数
  586. workbook.SaveAs(
  587. Filename: exportPath,
  588. FileFormat: XlFileFormat.xlOpenXMLWorkbook,
  589. Password: Type.Missing,
  590. WriteResPassword: Type.Missing,
  591. ReadOnlyRecommended: Type.Missing,
  592. CreateBackup: Type.Missing,
  593. AccessMode: XlSaveAsAccessMode.xlExclusive,
  594. ConflictResolution: Type.Missing,
  595. AddToMru: false,
  596. TextCodepage: Type.Missing,
  597. TextVisualLayout: Type.Missing,
  598. Local: Type.Missing
  599. );
  600. MessageBox.Show($"Excel文件已成功导出到: {exportPath}", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
  601. }
  602. catch (Exception ex)
  603. {
  604. MessageBox.Show($"生成 Excel 文件时出错: {ex.Message}", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  605. }
  606. finally
  607. {
  608. // 正确释放COM对象
  609. if (worksheet != null)
  610. {
  611. try
  612. {
  613. Marshal.ReleaseComObject(worksheet);
  614. }
  615. catch { }
  616. worksheet = null;
  617. }
  618. if (workbook != null)
  619. {
  620. try
  621. {
  622. workbook.Close(false);
  623. Marshal.ReleaseComObject(workbook);
  624. }
  625. catch { }
  626. workbook = null;
  627. }
  628. if (excelApp != null)
  629. {
  630. try
  631. {
  632. excelApp.Quit();
  633. Marshal.ReleaseComObject(excelApp);
  634. }
  635. catch { }
  636. excelApp = null;
  637. }
  638. if (!string.IsNullOrEmpty(tempTemplatePath) && File.Exists(tempTemplatePath))
  639. {
  640. try
  641. {
  642. File.Delete(tempTemplatePath);
  643. }
  644. catch (Exception ex)
  645. {
  646. }
  647. }
  648. GC.Collect();
  649. GC.WaitForPendingFinalizers();
  650. }
  651. }
  652. private void rulesAdd_Click(object sender, EventArgs e)
  653. {
  654. StringBuilder filterStr = new StringBuilder();
  655. if (!string.IsNullOrEmpty(rulesInput1.Text))
  656. {
  657. filterStr.Append($"WHERE instr(RULE_NAME,'{rulesInput1.Text}') > 0");
  658. }
  659. if (!string.IsNullOrEmpty(rulesInput2.Text))
  660. {
  661. if(filterStr.Length == 0)
  662. {
  663. filterStr.Append($"WHERE instr(RULE_VALUE,'{rulesInput2.Text}') > 0");
  664. }
  665. else
  666. {
  667. filterStr.Append($" and instr(RULE_VALUE, '{rulesInput2.Text}') > 0");
  668. }
  669. }
  670. Form rulesList = new RulesList("Add",_UserName);
  671. if (rulesList.ShowDialog() == DialogResult.OK)
  672. {
  673. MessageBox.Show("新增规则成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
  674. dt = ConnectDB.ExecuteSelect($@"SELECT RULE_ID ruleId,RULE_NAME RulesCol1, RULE_VALUE RulesCol2, RELE_REMARK RulesCol3,
  675. RULE_LENGTH RulesCol4,to_char(UPDATE_TIME, 'YYYY-MM-DD HH:Mi:SS') RulesCol5,UPDATE_USER RulesCol6 FROM g_packing_rules {filterStr.ToString()} order by UPDATE_TIME desc");
  676. RulesDatas.DataSource = dt;
  677. }
  678. }
  679. private void rulesQuery_Click(object sender, EventArgs e)
  680. {
  681. StringBuilder filterStr = new StringBuilder();
  682. if (!string.IsNullOrEmpty(rulesInput1.Text))
  683. {
  684. filterStr.Append($"WHERE instr(RULE_NAME,'{rulesInput1.Text}') > 0");
  685. }
  686. if (!string.IsNullOrEmpty(rulesInput2.Text))
  687. {
  688. if (filterStr.Length == 0)
  689. {
  690. filterStr.Append($"WHERE instr(RULE_VALUE,'{rulesInput2.Text}') > 0");
  691. }
  692. else
  693. {
  694. filterStr.Append($" and instr(RULE_VALUE, '{rulesInput2.Text}') > 0");
  695. }
  696. }
  697. dt = ConnectDB.ExecuteSelect($@"SELECT RULE_ID ruleId,RULE_NAME RulesCol1, RULE_VALUE RulesCol2, RELE_REMARK RulesCol3,
  698. RULE_LENGTH RulesCol4,to_char(UPDATE_TIME, 'YYYY-MM-DD HH:Mi:SS') RulesCol5,UPDATE_USER RulesCol6 FROM g_packing_rules {filterStr.ToString()} order by UPDATE_TIME desc");
  699. RulesDatas.DataSource = dt;
  700. }
  701. private void RulesDatas_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
  702. {
  703. if (e.RowIndex >= 0 && !RulesDatas.Rows[e.RowIndex].IsNewRow)
  704. {
  705. DataGridView dgv = sender as DataGridView;
  706. if (dgv != null)
  707. {
  708. DataGridViewRow selectedRow = dgv.Rows[e.RowIndex];
  709. string RULE_ID = selectedRow.Cells[0].Value.ToString();
  710. StringBuilder filterStr = new StringBuilder();
  711. if (!string.IsNullOrEmpty(rulesInput1.Text))
  712. {
  713. filterStr.Append($"WHERE instr(RULE_NAME,'{rulesInput1.Text}') > 0");
  714. }
  715. if (!string.IsNullOrEmpty(rulesInput2.Text))
  716. {
  717. if (filterStr.Length == 0)
  718. {
  719. filterStr.Append($"WHERE instr(RULE_VALUE,'{rulesInput2.Text}') > 0");
  720. }
  721. else
  722. {
  723. filterStr.Append($" and instr(RULE_VALUE, '{rulesInput2.Text}') > 0");
  724. }
  725. }
  726. Form rulesList = new RulesList("Modify",RULE_ID, _UserName);
  727. if (rulesList.ShowDialog() == DialogResult.OK)
  728. {
  729. MessageBox.Show("修改规则成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
  730. dt = ConnectDB.ExecuteSelect($@"SELECT RULE_ID ruleId,RULE_NAME RulesCol1, RULE_VALUE RulesCol2, RELE_REMARK RulesCol3,
  731. RULE_LENGTH RulesCol4,to_char(UPDATE_TIME, 'YYYY-MM-DD HH:Mi:SS') RulesCol5,UPDATE_USER RulesCol6 FROM g_packing_rules {filterStr.ToString()} order by UPDATE_TIME desc");
  732. RulesDatas.DataSource = dt;
  733. }
  734. }
  735. }
  736. }
  737. private void RulesDatas_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
  738. {
  739. if (e.RowIndex >= 0 && !RulesDatas.Rows[e.RowIndex].IsNewRow)
  740. {
  741. DataGridView dgv = sender as DataGridView;
  742. if (dgv != null)
  743. {
  744. DataGridViewRow selectedRow = dgv.Rows[e.RowIndex];
  745. if (dRules.Enabled)
  746. {
  747. dRules.Text = selectedRow.Cells[1].Value.ToString();
  748. curRuleId = selectedRow.Cells[0].Value.ToString();
  749. curRule = selectedRow.Cells[2].Value.ToString();
  750. curRuleLeng = selectedRow.Cells[4].Value.ToString();
  751. }
  752. }
  753. }
  754. }
  755. private void boxBtn_Click(object sender, EventArgs e)
  756. {
  757. BoxNo.Enabled = true;
  758. BoxNo.Focus();
  759. BoxNo.SelectAll();
  760. }
  761. private void settingRightInput1_Click(object sender, EventArgs e)
  762. {
  763. using (OpenFileDialog openFileDialog = new OpenFileDialog())
  764. {
  765. openFileDialog.Title = "请选择告警文件";
  766. openFileDialog.Filter = "可执行文件 (*.wav)|*.wav|所有文件 (*.*)|*.*";
  767. openFileDialog.FilterIndex = 1;
  768. openFileDialog.RestoreDirectory = true;
  769. if (!string.IsNullOrEmpty(settingRightInput1.Text) && System.IO.File.Exists(settingRightInput1.Text))
  770. {
  771. openFileDialog.InitialDirectory = System.IO.Path.GetDirectoryName(settingRightInput1.Text);
  772. }
  773. else
  774. {
  775. openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
  776. }
  777. if (openFileDialog.ShowDialog() == DialogResult.OK)
  778. {
  779. settingRightInput1.Text = openFileDialog.FileName;
  780. }
  781. }
  782. }
  783. private void settingRightInput2_Click(object sender, EventArgs e)
  784. {
  785. using (FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog())
  786. {
  787. folderBrowserDialog.Description = "请选择导出文件夹";
  788. if (!string.IsNullOrEmpty(settingRightInput2.Text) && System.IO.Directory.Exists(settingRightInput2.Text))
  789. {
  790. folderBrowserDialog.SelectedPath = settingRightInput2.Text;
  791. }
  792. else
  793. {
  794. folderBrowserDialog.SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); // folderBrowserDialog.SelectedPath = "";
  795. }
  796. if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
  797. {
  798. settingRightInput2.Text = folderBrowserDialog.SelectedPath;
  799. }
  800. }
  801. }
  802. private void QDdtp1_ValueChanged(object sender, EventArgs e)
  803. {
  804. if (QDdtp1.Value > QDdtp2.Value)
  805. {
  806. QDdtp1.Value = QDdtp2.Value.AddDays(-1);
  807. MessageBox.Show("时间不得大于最大时间", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  808. return;
  809. }
  810. minTime = QDdtp1.Value.ToString("yyyy-mm-dd hh:mm:ss");
  811. }
  812. private void DRulesBtn_Click(object sender, EventArgs e)
  813. {
  814. if (string.IsNullOrEmpty(dRules.Text))
  815. {
  816. MessageBox.Show("请选择条码规则", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  817. return;
  818. }
  819. dRules.Enabled = false;
  820. }
  821. private void DRulesBtn1_Click(object sender, EventArgs e)
  822. {
  823. dRules.Enabled = true;
  824. }
  825. private void QDdtp2_ValueChanged(object sender, EventArgs e)
  826. {
  827. if (QDdtp2.Value < QDdtp1.Value)
  828. {
  829. QDdtp2.Value = QDdtp1.Value.AddDays(1);
  830. MessageBox.Show("时间不得小于最小时间", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  831. return;
  832. }
  833. maxTime = QDdtp2.Value.ToString("yyyy-mm-dd hh:mm:ss");
  834. }
  835. private void PlaySound(string type)
  836. {
  837. if (type == "OK")
  838. {
  839. ShowMsg.Text = "Pass";
  840. ShowMsg.BackColor = Color.LawnGreen;
  841. }
  842. else
  843. {
  844. ShowMsg.Text = "Fail";
  845. ShowMsg.BackColor = Color.Red;
  846. }
  847. Task.Run(() => {
  848. if (type == "OK")
  849. {
  850. using (var stream = UAS_Tools_HY.Properties.Resources.OK)
  851. {
  852. SoundPlayer player = new SoundPlayer(stream);
  853. player.Play();
  854. }
  855. }
  856. else
  857. {
  858. if (string.IsNullOrEmpty(settingRightInput1.Text))
  859. {
  860. using (var stream = UAS_Tools_HY.Properties.Resources.NG)
  861. {
  862. SoundPlayer player = new SoundPlayer(stream);
  863. player.Play();
  864. }
  865. }
  866. else
  867. {
  868. string customPath = settingRightInput1.Text.Trim();
  869. if (File.Exists(customPath))
  870. {
  871. SoundPlayer player = new SoundPlayer(customPath);
  872. player.Play();
  873. }
  874. }
  875. }
  876. });
  877. }
  878. public void loadTime_Tick(object sender, EventArgs e)
  879. {
  880. string currentDate = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
  881. currTime.Text = currentDate;
  882. handTime.Value = new DateTime(DateTime.Now.Year,DateTime.Now.Month,DateTime.Now.Day,DateTime.Now.Hour,0, 0);
  883. }
  884. private async void FtpConnect_Click(object sender, EventArgs e)
  885. {
  886. if(FtpConnect.Text == "开启连接")
  887. {
  888. if (string.IsNullOrEmpty(FtpAccountVal.Text))
  889. {
  890. LogMessage("NG,请填写ftp账户");
  891. return;
  892. }
  893. if (string.IsNullOrEmpty(FtpPwVal.Text))
  894. {
  895. LogMessage("NG,请填写ftp密码");
  896. return;
  897. }
  898. if (string.IsNullOrEmpty(timerVal.Text))
  899. {
  900. LogMessage("NG,请填写间隔抓取文件时间");
  901. return;
  902. }
  903. if (string.IsNullOrEmpty(FtpPathVal.Text))
  904. {
  905. LogMessage("NG,请填写ftp抓取路径地址");
  906. return;
  907. }
  908. if (string.IsNullOrEmpty(FileCountVal.Text))
  909. {
  910. LogMessage("NG,请填写打包文件数");
  911. return;
  912. }
  913. FtpConnect.Enabled = false;
  914. FtpConnect.Text = "连接中...";
  915. LogMessage("开始测试连接...");
  916. bool testConnect = await TestFtpConnection(FtpPathVal.Text.Trim(), FtpAccountVal.Text.Trim(), FtpPwVal.Text.Trim());
  917. if (testConnect)
  918. {
  919. FtpAccountVal.Enabled = false;
  920. FtpPwVal.Enabled = false;
  921. timerVal.Enabled = false;
  922. FtpPathVal.Enabled = false;
  923. FileCountVal.Enabled = false;
  924. FtpConnect.Text = "关闭连接";
  925. FtpListen.Enabled = true;
  926. }
  927. else
  928. {
  929. FtpConnect.Enabled = true;
  930. FtpConnect.Text = "开启连接";
  931. }
  932. }
  933. else if(FtpConnect.Text == "关闭连接")
  934. {
  935. FtpAccountVal.Enabled = true;
  936. FtpPwVal.Enabled = true;
  937. timerVal.Enabled = true;
  938. FtpPathVal.Enabled = true;
  939. FileCountVal.Enabled = true;
  940. FtpConnect.Text = "开启连接";
  941. FtpListen.Enabled = false;
  942. }
  943. }
  944. public async Task<bool> TestFtpConnection(string ftpServer, string username, string password)
  945. {
  946. try
  947. {
  948. var request = (FtpWebRequest)WebRequest.Create(ftpServer);
  949. request.Method = WebRequestMethods.Ftp.ListDirectory;
  950. request.Credentials = new NetworkCredential(username, password);
  951. request.UsePassive = true;
  952. request.UseBinary = true;
  953. request.KeepAlive = false;
  954. request.Timeout = 10000;
  955. using (var response = await request.GetResponseAsync() as FtpWebResponse)
  956. {
  957. await Task.Run(() =>
  958. {
  959. LogMessage($"OK,FTP连接成功: {response.StatusDescription}");
  960. });
  961. return true;
  962. }
  963. }
  964. catch (WebException ex)
  965. {
  966. await Task.Run(() =>
  967. {
  968. if (ex.Response is FtpWebResponse response)
  969. {
  970. LogMessage($"NG,FTP连接失败,错误码: {(int)response.StatusCode} - {response.StatusDescription}");
  971. }
  972. else
  973. {
  974. LogMessage("NG,连接异常: " + ex.Message);
  975. }
  976. });
  977. return false;
  978. }
  979. catch (Exception ex)
  980. {
  981. await Task.Run(() =>
  982. {
  983. LogMessage($"NG,连接失败: " + ex.Message);
  984. });
  985. return false;
  986. }
  987. }
  988. private void FtpListen_Click(object sender, EventArgs e)
  989. {
  990. File_timer.Interval = Convert.ToInt32(timerVal.Text.Trim()) * 1000;
  991. if (FtpListen.Text == "开启监听")
  992. {
  993. FtpListen.Text = "关闭监听";
  994. FtpConnect.Enabled = false;
  995. File_timer.Start();
  996. Timer_Tick(null, null);
  997. }
  998. else if (FtpListen.Text == "关闭监听")
  999. {
  1000. FtpListen.Text = "开启监听";
  1001. FtpConnect.Enabled = true;
  1002. File_timer.Stop();
  1003. }
  1004. }
  1005. private void MsgBox_DrawItem(object sender, DrawItemEventArgs e)
  1006. {
  1007. e.DrawBackground();
  1008. Brush mybsh = Brushes.Black;
  1009. string msgStr = MsgBox.Items[e.Index].ToString();
  1010. Console.WriteLine();
  1011. if (MsgBox.Items[e.Index].ToString().Contains("OK"))
  1012. {
  1013. mybsh = Brushes.Green;
  1014. }
  1015. else if (MsgBox.Items[e.Index].ToString().Contains("NG"))
  1016. {
  1017. mybsh = Brushes.Red;
  1018. }
  1019. e.DrawFocusRectangle();
  1020. e.Graphics.DrawString(MsgBox.Items[e.Index].ToString(), e.Font, mybsh, e.Bounds, StringFormat.GenericDefault);
  1021. }
  1022. private void LogMessage(string message)
  1023. {
  1024. if (MsgBox.InvokeRequired)
  1025. {
  1026. MsgBox.Invoke(new Action<string>(LogMessage), message);
  1027. return;
  1028. }
  1029. MsgBox.Items.Add($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {message}");
  1030. MsgBox.TopIndex = MsgBox.Items.Count - 1;
  1031. MsgBox.DrawMode = DrawMode.OwnerDrawFixed;
  1032. }
  1033. private void Timer_Tick(object sender, EventArgs e)
  1034. {
  1035. try
  1036. {
  1037. string childSaveFiles = Path.Combine(saveFiles, DateTime.Now.ToString("yyyyMMdd"));
  1038. if (!Directory.Exists(childSaveFiles))
  1039. {
  1040. Directory.CreateDirectory(childSaveFiles);
  1041. currentNum = 1;
  1042. LogMessage($"创建本地文件夹: {childSaveFiles}");
  1043. }
  1044. string ftpServer = FtpPathVal.Text.Trim();
  1045. string remoteFolderPath = "";
  1046. string username = FtpAccountVal.Text.Trim();
  1047. string password = FtpPwVal.Text.Trim();
  1048. List<string> fileList = GetFtpFileList(ftpServer, remoteFolderPath, username, password);
  1049. if (fileList.Count == 0)
  1050. {
  1051. LogMessage($"远程文件夹 '{remoteFolderPath}' 中没有文件");
  1052. return;
  1053. }
  1054. int successCount = 0;
  1055. int failCount = 0;
  1056. LogMessage($"开始下载 {fileList.Count} 个文件...");
  1057. foreach (string remoteFile in fileList)
  1058. {
  1059. if (!Directory.Exists(childSaveFiles))
  1060. {
  1061. Directory.CreateDirectory(childSaveFiles);
  1062. }
  1063. string remoteFilePath = $"{remoteFolderPath.TrimEnd('/')}/{remoteFile}";
  1064. string localFilePath = Path.Combine(childSaveFiles, remoteFile);
  1065. if (DownloadSingleFile(ftpServer, remoteFilePath, localFilePath, username, password))
  1066. {
  1067. successCount++;
  1068. }
  1069. else
  1070. {
  1071. failCount++;
  1072. }
  1073. string[] files = Directory.GetFiles(childSaveFiles);
  1074. string zipFilePath = Path.Combine(Path.GetDirectoryName(childSaveFiles), Path.GetFileName(childSaveFiles) + $"-{currentNum}.zip");
  1075. if (Convert.ToInt32(FileCountVal.Text.Trim()) == files.Length)
  1076. {
  1077. CompressFolder(childSaveFiles, zipFilePath);
  1078. currentNum++;
  1079. }
  1080. }
  1081. LogMessage($"下载完成: 成功 {successCount} 个, 失败 {failCount} 个");
  1082. }
  1083. catch (Exception ex)
  1084. {
  1085. LogMessage($"NG,自动获取文件失败,Error: {ex.Message}");
  1086. }
  1087. }
  1088. private List<string> GetFtpFileList(string ftpServer, string folderPath, string username, string password)
  1089. {
  1090. List<string> fileList = new List<string>();
  1091. try
  1092. {
  1093. string uri = $"{ftpServer.TrimEnd('/')}/{folderPath.TrimStart('/')}";
  1094. var request = (FtpWebRequest)WebRequest.Create(uri);
  1095. request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
  1096. request.Credentials = new NetworkCredential(username, password);
  1097. request.UsePassive = true;
  1098. request.UseBinary = true;
  1099. request.KeepAlive = false;
  1100. using (var response = (FtpWebResponse)request.GetResponse())
  1101. using (var responseStream = response.GetResponseStream())
  1102. using (var reader = new StreamReader(responseStream))
  1103. {
  1104. string line;
  1105. while ((line = reader.ReadLine()) != null)
  1106. {
  1107. if (!string.IsNullOrWhiteSpace(line))
  1108. {
  1109. string[] parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
  1110. if (parts.Length >= 3)
  1111. {
  1112. //string fileName = parts[8];
  1113. //if (!parts[0].StartsWith("d") && fileName != "." && fileName != "..")
  1114. //{
  1115. // fileList.Add(fileName);
  1116. //}
  1117. string fileName = parts[parts.Length - 1];
  1118. if (fileName.Contains("."))
  1119. {
  1120. fileList.Add(fileName);
  1121. }
  1122. }
  1123. }
  1124. }
  1125. }
  1126. }
  1127. catch (Exception ex)
  1128. {
  1129. LogMessage($"获取文件列表失败: {ex.Message}");
  1130. }
  1131. return fileList;
  1132. }
  1133. private bool DownloadSingleFile(string ftpServer, string remoteFilePath, string localFilePath, string username, string password)
  1134. {
  1135. try
  1136. {
  1137. bool downloadSuccess = false;
  1138. string uri = $"{ftpServer.TrimEnd('/')}/{remoteFilePath.TrimStart('/')}";
  1139. var request = (FtpWebRequest)WebRequest.Create(uri);
  1140. request.Method = WebRequestMethods.Ftp.DownloadFile;
  1141. request.Credentials = new NetworkCredential(username, password);
  1142. request.UsePassive = true;
  1143. request.UseBinary = true;
  1144. request.KeepAlive = false;
  1145. using (var response = (FtpWebResponse)request.GetResponse())
  1146. using (var responseStream = response.GetResponseStream())
  1147. using (var fileStream = File.Create(localFilePath))
  1148. {
  1149. byte[] buffer = new byte[4096];
  1150. int bytesRead;
  1151. while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
  1152. {
  1153. fileStream.Write(buffer, 0, bytesRead);
  1154. }
  1155. downloadSuccess = true;
  1156. LogMessage($"OK,文件下载成功: {remoteFilePath} -> {localFilePath}");
  1157. if (downloadSuccess)
  1158. {
  1159. var deleteRequest = (FtpWebRequest)WebRequest.Create(uri);
  1160. deleteRequest.Method = WebRequestMethods.Ftp.DeleteFile;
  1161. deleteRequest.Credentials = new NetworkCredential(username, password);
  1162. deleteRequest.UsePassive = true;
  1163. deleteRequest.KeepAlive = false;
  1164. using (var deleteResponse = (FtpWebResponse)deleteRequest.GetResponse())
  1165. {
  1166. LogMessage($"OK,服务器文件删除成功: {remoteFilePath}");
  1167. }
  1168. }
  1169. return true;
  1170. }
  1171. }
  1172. catch (WebException ex)
  1173. {
  1174. if (ex.Response is FtpWebResponse response)
  1175. {
  1176. LogMessage($"NG,下载失败 {remoteFilePath}: {(int)response.StatusCode} - {response.StatusDescription}");
  1177. }
  1178. else
  1179. {
  1180. LogMessage($"NG,下载失败 {remoteFilePath}: {ex.Message}");
  1181. }
  1182. return false;
  1183. }
  1184. catch (Exception ex)
  1185. {
  1186. LogMessage($"NG,下载失败 {remoteFilePath}: {ex.Message}");
  1187. return false;
  1188. }
  1189. }
  1190. private string CreateFtpDirectoryIfNotExists(string ftpDirectoryPath, string username, string password)
  1191. {
  1192. try
  1193. {
  1194. FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpDirectoryPath);
  1195. request.Method = WebRequestMethods.Ftp.MakeDirectory;
  1196. request.Credentials = new NetworkCredential(username, password);
  1197. request.UsePassive = true;
  1198. request.UseBinary = true;
  1199. request.KeepAlive = false;
  1200. using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
  1201. {
  1202. response.Close();
  1203. return "OK,目录创建成功: " + response.StatusDescription;
  1204. }
  1205. }
  1206. catch (WebException ex)
  1207. {
  1208. if (ex.Response is FtpWebResponse response && response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
  1209. {
  1210. return "OK,目录已存在: " + response.StatusDescription;
  1211. }
  1212. else
  1213. {
  1214. return "NG,创建目录时发生错误: " + ex.Message;
  1215. }
  1216. }
  1217. }
  1218. private void CompressFile(string sourceFile, string zipPath)
  1219. {
  1220. try
  1221. {
  1222. using (FileStream zipToOpen = new FileStream(zipPath, FileMode.Create))
  1223. using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Create))
  1224. {
  1225. string fileName = Path.GetFileName(sourceFile);
  1226. ZipArchiveEntry readmeEntry = archive.CreateEntry(fileName);
  1227. using (Stream stream = readmeEntry.Open())
  1228. using (FileStream fileStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read))
  1229. {
  1230. fileStream.CopyTo(stream);
  1231. }
  1232. }
  1233. LogMessage($"OK,文件已压缩到:{zipPath}");
  1234. }
  1235. catch (Exception ex)
  1236. {
  1237. LogMessage($"NG,压缩失败:{ex.Message}");
  1238. }
  1239. }
  1240. private void CompressFolder(string sourceFolder, string zipPath)
  1241. {
  1242. try
  1243. {
  1244. if (File.Exists(zipPath))
  1245. {
  1246. try
  1247. {
  1248. File.Delete(zipPath);
  1249. }
  1250. catch (IOException ex)
  1251. {
  1252. LogMessage($"NG,无法删除已存在的文件,可能被其他程序占用:{ex.Message}");
  1253. return;
  1254. }
  1255. catch (UnauthorizedAccessException ex)
  1256. {
  1257. LogMessage($"NG,没有权限删除文件:{ex.Message}");
  1258. return;
  1259. }
  1260. }
  1261. ZipFile.CreateFromDirectory(sourceFolder, zipPath);
  1262. Directory.Delete(sourceFolder, true);
  1263. LogMessage($"OK,文件已压缩到:{zipPath}");
  1264. }
  1265. catch (UnauthorizedAccessException ex)
  1266. {
  1267. LogMessage($"NG,访问被拒绝:{ex.Message}");
  1268. }
  1269. catch (Exception ex)
  1270. {
  1271. LogMessage($"NG,压缩失败:{ex.Message}");
  1272. }
  1273. }
  1274. private void listenVal_Click(object sender, EventArgs e)
  1275. {
  1276. using (FolderBrowserDialog folderDialog = new FolderBrowserDialog())
  1277. {
  1278. folderDialog.Description = "请选择监控文件夹";
  1279. folderDialog.SelectedPath = listenVal.Text;
  1280. if (folderDialog.ShowDialog() == DialogResult.OK)
  1281. {
  1282. listenVal.Text = folderDialog.SelectedPath;
  1283. }
  1284. }
  1285. }
  1286. private void handPathVal_Click(object sender, EventArgs e)
  1287. {
  1288. using (FolderBrowserDialog folderDialog = new FolderBrowserDialog())
  1289. {
  1290. folderDialog.Description = "请选择导出文件夹";
  1291. folderDialog.SelectedPath = handPathVal.Text;
  1292. if (folderDialog.ShowDialog() == DialogResult.OK)
  1293. {
  1294. handPathVal.Text = folderDialog.SelectedPath;
  1295. }
  1296. }
  1297. }
  1298. private void buildConfirm_Click(object sender, EventArgs e)
  1299. {
  1300. if (buildConfirm.Text == "确定")
  1301. {
  1302. if (string.IsNullOrEmpty(handExeVal.Text))
  1303. {
  1304. LogMessage($"NG,请填写处理间隔时间");
  1305. return;
  1306. }
  1307. if (string.IsNullOrEmpty(listenVal.Text))
  1308. {
  1309. LogMessage($"NG,请填写监控路径");
  1310. return;
  1311. }
  1312. if (string.IsNullOrEmpty(handPathVal.Text))
  1313. {
  1314. LogMessage($"NG,请填写导出路径");
  1315. return;
  1316. }
  1317. handExeVal.Enabled = false;
  1318. handTime.Enabled = false;
  1319. listenVal.Enabled = false;
  1320. handPathVal.Enabled = false;
  1321. buildConfirm.Text = "取消";
  1322. }
  1323. else
  1324. {
  1325. handExeVal.Enabled = true;
  1326. handTime.Enabled = true;
  1327. listenVal.Enabled = true;
  1328. handPathVal.Enabled = true;
  1329. buildConfirm.Text = "确定";
  1330. }
  1331. }
  1332. private void buildStart_Click(object sender, EventArgs e)
  1333. {
  1334. if(buildStart.Text == "开启处理")
  1335. {
  1336. buildStart.Text = "关闭处理";
  1337. File_timer1.Interval = Convert.ToInt32(handExeVal.Text) * 60 * 1000;
  1338. File_timer1.Start();
  1339. FileTimer_Tick(null, null);
  1340. }
  1341. else
  1342. {
  1343. buildStart.Text = "开启处理";
  1344. File_timer.Stop();
  1345. }
  1346. }
  1347. private async void FileTimer_Tick(object sender, EventArgs e)
  1348. {
  1349. _currentOperationCts?.Cancel();
  1350. _currentOperationCts = new CancellationTokenSource();
  1351. try
  1352. {
  1353. await Task.Run(() => ProcessFilesInternal(_currentOperationCts.Token));
  1354. }
  1355. catch (OperationCanceledException)
  1356. {
  1357. LogMessage("文件处理操作被新任务取消。");
  1358. }
  1359. catch (Exception ex)
  1360. {
  1361. LogMessage($"NG,定时器任务启动失败: {ex}");
  1362. }
  1363. /*try
  1364. {
  1365. string[] txtFiles = Directory.GetFiles(listenVal.Text, $"*.json");
  1366. string currentHour = DateTime.Now.ToString("yyyyMMdd_hh");
  1367. string outPath = Path.Combine(handPathVal.Text, currentHour + "_Count_" + txtFiles.Length);
  1368. if (!Directory.Exists(outPath))
  1369. {
  1370. Directory.CreateDirectory(outPath);
  1371. }
  1372. foreach (string file in txtFiles)
  1373. {
  1374. string targetFile = Path.Combine(outPath, Path.GetFileName(file));
  1375. if (File.Exists(targetFile))
  1376. {
  1377. File.Delete(targetFile);
  1378. }
  1379. File.Move(file, targetFile);
  1380. }
  1381. string zipPath = outPath + ".zip";
  1382. if (File.Exists(zipPath))
  1383. {
  1384. File.Delete(zipPath);
  1385. }
  1386. ZipFile.CreateFromDirectory(outPath, zipPath);
  1387. LogMessage($"OK,文件已压缩到:{zipPath}");
  1388. }
  1389. catch(Exception ex)
  1390. {
  1391. LogMessage($"NG,解析文件列表失败: {ex.Message}");
  1392. }*/
  1393. }
  1394. private void ProcessFilesInternal(CancellationToken cancellationToken)
  1395. {
  1396. try
  1397. {
  1398. var txtFiles = Directory.EnumerateFiles(listenVal.Text, "*.json", SearchOption.TopDirectoryOnly).ToList();
  1399. int fileCount = txtFiles.Count;
  1400. if (fileCount == 0)
  1401. {
  1402. LogMessage("没有找到需要处理的 .json 文件。");
  1403. return;
  1404. }
  1405. cancellationToken.ThrowIfCancellationRequested();
  1406. LogMessage($"已找到找到 {fileCount} 个json文件,开始处理...");
  1407. string currentHour = DateTime.Now.ToString("yyyyMMdd_HH");
  1408. string outPath = Path.Combine(handPathVal.Text, $"{currentHour}_{Convert.ToInt32(handExeVal.Text)}_Count_{fileCount}");
  1409. cancellationToken.ThrowIfCancellationRequested();
  1410. if (!Directory.Exists(outPath))
  1411. {
  1412. Directory.CreateDirectory(outPath);
  1413. }
  1414. int movedCount = 0;
  1415. foreach (string file in txtFiles)
  1416. {
  1417. cancellationToken.ThrowIfCancellationRequested();
  1418. string targetFile = Path.Combine(outPath, Path.GetFileName(file));
  1419. if (File.Exists(targetFile))
  1420. {
  1421. File.Delete(targetFile);
  1422. }
  1423. File.Move(file, targetFile);
  1424. movedCount++;
  1425. if (movedCount % 1000 == 0)
  1426. {
  1427. LogMessage($"已移动 {movedCount}/{fileCount} 个文件...");
  1428. }
  1429. }
  1430. LogMessage($"成功移动 {movedCount} 个文件到 '{outPath}'");
  1431. string zipPath = outPath + ".zip";
  1432. cancellationToken.ThrowIfCancellationRequested();
  1433. if (File.Exists(zipPath))
  1434. {
  1435. File.Delete(zipPath);
  1436. }
  1437. ZipFile.CreateFromDirectory(outPath, zipPath);
  1438. //Directory.Delete(outPath, true);
  1439. LogMessage($"OK, {fileCount} 个文件已成功压缩到: {zipPath}");
  1440. }
  1441. catch (OperationCanceledException)
  1442. {
  1443. LogMessage("OK, 文件处理操作被用户取消。");
  1444. }
  1445. catch (UnauthorizedAccessException ex)
  1446. {
  1447. LogMessage($"NG, 访问被拒绝,可能没有足够权限读写文件或目录: {ex.Message}");
  1448. }
  1449. catch (DirectoryNotFoundException ex)
  1450. {
  1451. LogMessage($"NG, 指定的路径不存在: {ex.Message}");
  1452. }
  1453. catch (IOException ex)
  1454. {
  1455. LogMessage($"NG, 文件 I/O 错误: {ex.Message}");
  1456. }
  1457. catch (Exception ex)
  1458. {
  1459. LogMessage($"NG, 文件处理过程中发生未知错误: {ex}");
  1460. }
  1461. }
  1462. }
  1463. }