MailNotice.cs 103 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813
  1. using Cksoft.Data;
  2. using Cksoft.Data.Repository;
  3. using Cksoft.Unity;
  4. using DllEapDal;
  5. using DllEapDal.OFILM;
  6. using DllEapEntity;
  7. using DllEapEntity.OFILM;
  8. using Microsoft.EntityFrameworkCore.Internal;
  9. using Microsoft.Extensions.Logging;
  10. using System;
  11. using System.Collections.Generic;
  12. using System.IO;
  13. using System.Linq;
  14. using System.Net;
  15. using System.Net.Mail;
  16. using System.Text;
  17. using System.Threading;
  18. using System.Threading.Tasks;
  19. namespace DllEapBll
  20. {
  21. public class MailNotice
  22. {
  23. private static ILogger myloger = AppConfigurtaionServices.MyLog;
  24. public static async Task<string> DisconnectionNotice(int type)
  25. {
  26. string toMail = "";
  27. string ccMail = "";
  28. StringBuilder body = new StringBuilder();
  29. MailSettings mail = null;
  30. List<FileAttachment> file = new List<FileAttachment>();
  31. using (IDatabase db = DbFactory.Base("eapslave"))
  32. {
  33. var dal = new MailSettingsDal(db);
  34. string code = AppConfigurtaionServices.Configuration["DisConnNoticeCode"];
  35. mail = dal.GetMailSettingsByCode(code);
  36. if (mail == null)
  37. {
  38. return "邮件代码不存在";
  39. }
  40. List<MailReceiver> receiverList = dal.GetMailReceiverByMailId(mail.ID).ToList();
  41. if (receiverList == null || !receiverList.Any())
  42. {
  43. return "未设置收件人";
  44. }
  45. toMail = receiverList.Where(r => r.SendType == 1).Select(r => r.MailAddress).Join(";");
  46. ccMail = receiverList.Where(r => r.SendType == 2).Select(r => r.MailAddress).Join(";");
  47. //List<MacStatus01> macList = new MacStatusDal(db).GetMacStatus01ByStatusID(1).ToList();
  48. var dalMac = new MacRecipeDal(db);
  49. string errorinfo = string.Empty;
  50. int total;
  51. var macList = dalMac.GetMacRecipeDtos("", 1, 10000, "MacCode", "asc", out total, ref errorinfo);
  52. macList = macList.Where(m => !string.IsNullOrEmpty(m.Factory) && !m.Factory.Contains("临时区域"));
  53. if (macList == null || macList.Count() == 0)
  54. {
  55. return "未查询到设备";
  56. }
  57. body.Append($"<h3>{mail.MailBody}</h3>");
  58. //body.Append($"<h3>{DateTime.Today.AddDays(-1).ToString("yyyy-MM-dd")}</h3>");
  59. body.Append(@"<table cellpadding='3' style='border-collapse: collapse; border: 1px solid black'>
  60. <tr>
  61. <th style='border: 1px solid black'>园区</th>
  62. <th style='border: 1px solid black'>设备类型</th>
  63. <th style='border: 1px solid black'>总数量</th>
  64. <th style='border: 1px solid black'>离线数量</th>
  65. <th style='border: 1px solid black'>离线率</th>
  66. </tr>");
  67. var factoryList = macList.GroupBy(m => m.Factory);
  68. foreach (var f in factoryList)
  69. {
  70. //每个园区所有状态按机型分组
  71. var pCodeList = macList.Where(m => m.Factory == f.Key).GroupBy(m => m.PCode);
  72. //每个园区离线状态按机型分组
  73. var pCodeDisConnList = macList.Where(m => m.Factory == f.Key && m.StatusID == 1).GroupBy(m => m.PCode);
  74. int i = 0;
  75. int totalCount = 0;
  76. int disConnTotalCount = 0;
  77. foreach (var p in pCodeList)
  78. {
  79. //每个机型的总数
  80. int count = p.Count();
  81. //每个机型离线的总数
  82. int disConnCount = pCodeDisConnList.Where(m => m.Key == p.Key).Any() ? pCodeDisConnList.Where(m => m.Key == p.Key).First().Count() : 0;
  83. if (i == 0)
  84. {
  85. body.Append($@"<tr><td rowspan='{pCodeList.Count() + 1}' style='border: 1px solid black'>{f.Key}</td>
  86. <td style='border: 1px solid black'>{p.Key}</td>
  87. <td style='border: 1px solid black'>{count}</td>
  88. <td style='border: 1px solid black'>{disConnCount}</td>
  89. <td style='border: 1px solid black'>{(Convert.ToDouble(disConnCount) * 100 / Convert.ToDouble(count)).ToString("f2")}%</td>
  90. </tr>");
  91. }
  92. else
  93. {
  94. body.Append($@"<tr>
  95. <td style='border: 1px solid black'>{p.Key}</td>
  96. <td style='border: 1px solid black'>{count}</td>
  97. <td style='border: 1px solid black'>{disConnCount}</td>
  98. <td style='border: 1px solid black'>{(Convert.ToDouble(disConnCount) * 100 / Convert.ToDouble(count)).ToString("f2")}%</td>
  99. </tr>");
  100. }
  101. totalCount += count;
  102. disConnTotalCount += disConnCount;
  103. i++;
  104. }
  105. body.Append($@"<tr><td style='border: 1px solid black'>总计</td>
  106. <td style='border: 1px solid black'>{totalCount}</td>
  107. <td style='border: 1px solid black'>{disConnTotalCount}</td>
  108. <td style='border: 1px solid black'>{(Convert.ToDouble(disConnTotalCount) * 100 / Convert.ToDouble(totalCount)).ToString("f2")}%</td>
  109. </tr>");
  110. }
  111. body.Append("</table>");
  112. var macListDisConn = macList.Where(m => !string.IsNullOrEmpty(m.Factory) && m.StatusID == 1).OrderBy(m => m.Factory).OrderBy(m => m.MacCode);
  113. if (macListDisConn.Any())
  114. {
  115. StringBuilder sb = new StringBuilder();
  116. sb.Append("设备ID,设备类型,当前IP,MAC地址,园区,楼层,最新程序名称,连接状态");
  117. sb.AppendLine();
  118. foreach (var mac in macListDisConn)
  119. {
  120. sb.Append($"{mac.MacCode},{mac.PCode},{mac.RealIp},{mac.MacAddress},{mac.Factory},{mac.Floor},{mac.ProgramName},{mac.StatusName}");
  121. sb.AppendLine();
  122. }
  123. if (type == 1)
  124. {
  125. MemoryStream stream = new MemoryStream();
  126. StreamWriter write = new StreamWriter(stream, Encoding.UTF8);
  127. write.Write(sb.ToString());
  128. write.Flush();
  129. write.Close();
  130. write.Dispose();
  131. file.Add(new FileAttachment
  132. {
  133. FileContent = stream.ToArray(),
  134. FileName = DateTime.Today.ToString("yyyy-MM-dd") + mail.MailSubject + ".xls",
  135. });
  136. }
  137. else
  138. {
  139. string path = mail.MailSubject + ".xls";
  140. FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write);
  141. StreamWriter write = new StreamWriter(fs, Encoding.UTF8);
  142. write.Write(sb.ToString());
  143. write.Close();
  144. fs.Close();
  145. FileInfo fileInfo = new FileInfo(path);
  146. file.Add(new FileAttachment
  147. {
  148. Stream = fileInfo.OpenRead(),
  149. FileName = mail.MailSubject + ".xls",
  150. });
  151. }
  152. }
  153. }
  154. string errorinfoMail = "";
  155. if (type == 1)
  156. {
  157. myloger.LogError($"机台断线邮件发送开始");
  158. SendMail(mail.MailServer, mail.MailPort, mail.MailAccount, mail.MailPwd, toMail, ccMail, mail.MailSubject, body.ToString(), ref errorinfoMail, "", file, true);
  159. myloger.LogError($"机台断线邮件发送结束{errorinfoMail}");
  160. //SendMail("smtp.qq.com", "25", "404808639@qq.com", "kzxrczpnanyycbac", "404808639@qq.com", "", "机台断网邮件监控", errorinfoMail, ref errorinfoMail, "", file, true);
  161. }
  162. else
  163. {
  164. SendByMailKit(mail.MailServer, mail.MailPort, mail.MailAccount, mail.MailPwd, toMail, ccMail, mail.MailSubject, body.ToString(), ref errorinfoMail, file);
  165. }
  166. return errorinfoMail;
  167. }
  168. /// <summary>
  169. /// 机台系统IP与实际IP不一致邮件提醒
  170. /// </summary>
  171. /// <returns></returns>
  172. public static async Task<string> IPDifferentNotice()
  173. {
  174. string toMail = "";
  175. string ccMail = "";
  176. StringBuilder body = new StringBuilder();
  177. MailSettings mail = null;
  178. List<FileAttachment> file = new List<FileAttachment>();
  179. using (IDatabase db = DbFactory.Base("eapslave"))
  180. {
  181. var dal = new MailSettingsDal(db);
  182. string code = AppConfigurtaionServices.Configuration["IPDifferentNoticeCode"];
  183. mail = dal.GetMailSettingsByCode(code);
  184. if (mail == null)
  185. {
  186. return "邮件代码不存在";
  187. }
  188. List<MailReceiver> receiverList = dal.GetMailReceiverByMailId(mail.ID).ToList();
  189. if (receiverList == null || !receiverList.Any())
  190. {
  191. return "未设置收件人";
  192. }
  193. toMail = receiverList.Where(r => r.SendType == 1).Select(r => r.MailAddress).Join(";");
  194. ccMail = receiverList.Where(r => r.SendType == 2).Select(r => r.MailAddress).Join(";");
  195. var dalMac = new MachineDal(db);
  196. var macList = dalMac.GetMachineList();
  197. macList = macList.Where(m => !string.IsNullOrEmpty(m.FactoryName) && !m.FactoryName.Contains("临时区域"));
  198. var sql = "select a.id from machine a " +
  199. "left join macstatus01 b on a.fcode=b.maccode " +
  200. "where b.statusid=204906";
  201. var shutDownMacIds = db.FindList<string>(sql)?.Select(c => Convert.ToInt32(c));
  202. if (macList == null || macList.Count() == 0)
  203. {
  204. return "未查询到设备";
  205. }
  206. body.Append($"<h3>{mail.MailBody}</h3>");
  207. body.Append(@"<table cellpadding='3' style='border-collapse: collapse; border: 1px solid black'>
  208. <tr>
  209. <th style='border: 1px solid black'>园区</th>
  210. <th style='border: 1px solid black'>设备类型</th>
  211. <th style='border: 1px solid black'>总数量</th>
  212. <th style='border: 1px solid black'>ip不一致数量</th>
  213. <th style='border: 1px solid black'>ip不一致率</th>
  214. </tr>");
  215. var factoryList = macList.GroupBy(m => m.FactoryName);
  216. foreach (var f in factoryList)
  217. {
  218. //每个园区所有机台按机型分组
  219. var pCodeList = macList.Where(m => m.FactoryName == f.Key).GroupBy(m => m.MModeCode);
  220. //每个园区ip不一致按机型分组
  221. var pCodeDisConnList = macList.Where(m => m.FactoryName == f.Key && (string.IsNullOrEmpty(m.RealIP) || !m.RealIP.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).
  222. Contains(m.IPAddress)) && !shutDownMacIds.Contains(m.ID)).GroupBy(m => m.MModeCode);
  223. int i = 0;
  224. int totalCount = 0;
  225. int disConnTotalCount = 0;
  226. foreach (var p in pCodeList)
  227. {
  228. //每个机型的总数
  229. int count = p.Count();
  230. //每个机型离线的总数
  231. int disConnCount = pCodeDisConnList.Where(m => m.Key == p.Key).Any() ? pCodeDisConnList.Where(m => m.Key == p.Key).First().Count() : 0;
  232. if (i == 0)
  233. {
  234. body.Append($@"<tr><td rowspan='{pCodeList.Count() + 1}' style='border: 1px solid black'>{f.Key}</td>
  235. <td style='border: 1px solid black'>{p.Key}</td>
  236. <td style='border: 1px solid black'>{count}</td>
  237. <td style='border: 1px solid black'>{disConnCount}</td>
  238. <td style='border: 1px solid black'>{(Convert.ToDouble(disConnCount) * 100 / Convert.ToDouble(count)).ToString("f2")}%</td>
  239. </tr>");
  240. }
  241. else
  242. {
  243. body.Append($@"<tr>
  244. <td style='border: 1px solid black'>{p.Key}</td>
  245. <td style='border: 1px solid black'>{count}</td>
  246. <td style='border: 1px solid black'>{disConnCount}</td>
  247. <td style='border: 1px solid black'>{(Convert.ToDouble(disConnCount) * 100 / Convert.ToDouble(count)).ToString("f2")}%</td>
  248. </tr>");
  249. }
  250. totalCount += count;
  251. disConnTotalCount += disConnCount;
  252. i++;
  253. }
  254. body.Append($@"<tr><td style='border: 1px solid black'>总计</td>
  255. <td style='border: 1px solid black'>{totalCount}</td>
  256. <td style='border: 1px solid black'>{disConnTotalCount}</td>
  257. <td style='border: 1px solid black'>{(Convert.ToDouble(disConnTotalCount) * 100 / Convert.ToDouble(totalCount)).ToString("f2")}%</td>
  258. </tr>");
  259. }
  260. body.Append("</table>");
  261. var macListDisConn = macList.Where(m => string.IsNullOrEmpty(m.RealIP) || !m.RealIP.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).
  262. Contains(m.IPAddress))
  263. .Where(m => !shutDownMacIds.Contains(m.ID))
  264. .OrderBy(m => m.FactoryName).OrderBy(m => m.FCode);
  265. if (macListDisConn.Any())
  266. {
  267. StringBuilder sb = new StringBuilder();
  268. sb.Append("设备ID,设备名称,设备类型,IP地址,实际IP,MAC地址,园区,楼层");
  269. sb.AppendLine();
  270. foreach (var mac in macListDisConn)
  271. {
  272. sb.Append($"{mac.FCode},{mac.FName},{mac.MModeCode},{mac.IPAddress},{(string.IsNullOrEmpty(mac.RealIP) ? "" : mac.RealIP.Replace(",", " | "))},{mac.MacAddress},{mac.FactoryName},{mac.Floor}");
  273. sb.AppendLine();
  274. }
  275. MemoryStream stream = new MemoryStream();
  276. StreamWriter write = new StreamWriter(stream, Encoding.UTF8);
  277. write.Write(sb.ToString());
  278. write.Flush();
  279. write.Close();
  280. write.Dispose();
  281. file.Add(new FileAttachment
  282. {
  283. FileContent = stream.ToArray(),
  284. FileName = DateTime.Today.ToString("yyyy-MM-dd") + mail.MailSubject + ".xls",
  285. });
  286. }
  287. }
  288. string errorinfoMail = "";
  289. myloger.LogError($"机台系统IP与实际IP不一致邮件发送开始");
  290. SendMail(mail.MailServer, mail.MailPort, mail.MailAccount, mail.MailPwd, toMail, ccMail, mail.MailSubject, body.ToString(), ref errorinfoMail, "", file, true);
  291. myloger.LogError($"机台系统IP与实际IP不一致邮件发送结束{errorinfoMail}");
  292. return errorinfoMail;
  293. }
  294. /// <summary>
  295. /// AA抛料率未采集预警
  296. /// </summary>
  297. /// <returns></returns>
  298. public static async Task<string> AAMaterialUploadErrorNotice()
  299. {
  300. var startTime = DateTime.Now.AddDays(-2).ToString("yyyy-MM-dd 20:30:00");
  301. var endTime = DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd 20:30:00");
  302. var errorinfo = string.Empty;
  303. string toMail = "";
  304. string ccMail = "";
  305. StringBuilder body = new StringBuilder();
  306. MailSettings mail = null;
  307. List<FileAttachment> file = new List<FileAttachment>();
  308. using (IDatabase db = DbFactory.Base("eapslave"))
  309. {
  310. var dal = new MailSettingsDal(db);
  311. string code = AppConfigurtaionServices.Configuration["AAMaterialErrorNotice"];
  312. mail = dal.GetMailSettingsByCode(code);
  313. if (mail == null)
  314. {
  315. return "邮件代码不存在";
  316. }
  317. List<MailReceiver> receiverList = dal.GetMailReceiverByMailId(mail.ID).ToList();
  318. if (receiverList == null || !receiverList.Any())
  319. {
  320. return "未设置收件人";
  321. }
  322. // 测试
  323. //receiverList = receiverList.Where(c => c.Name == "韩慧鑫").ToList();
  324. toMail = receiverList.Where(r => r.SendType == 1).Select(r => r.MailAddress).Join(";");
  325. ccMail = receiverList.Where(r => r.SendType == 2).Select(r => r.MailAddress).Join(";");
  326. var macDal = new MachineDal(db);
  327. var aaMacs = macDal.GetMachineList().Where(c => c.FCode.StartsWith("AA") && !c.FactoryName.Contains("临时区域"));
  328. if (AppConfigurtaionServices.Configuration["IncludeTrialProduce"] == null
  329. || !Convert.ToBoolean(AppConfigurtaionServices.Configuration["IncludeTrialProduce"]))
  330. {
  331. aaMacs = aaMacs.Where(c => !c.PlantName.Contains("试产")
  332. && !c.Floor.Contains("试产"));
  333. }
  334. var sql = $@"select distinct FCode from maccountdetail a
  335. left join maccountmst b on a.MstID=b.ID
  336. left join machine c on b.MacID=c.ID where 1=1
  337. and b.SDate>'{startTime}' and b.SDate<'{Convert.ToDateTime(startTime).AddHours(12).ToString("yyyy-MM-dd HH:mm:ss")}'
  338. and a.typeid=0 and a.fcount>0
  339. and c.FCode like 'AA%'";
  340. var macCodesN = db.FindList<string>(sql);
  341. IEnumerable<Machine> runMacsN = new List<Machine>();
  342. if (macCodesN != null && macCodesN.Count() > 0)
  343. runMacsN = aaMacs.Where(c => macCodesN.Contains(c.FCode));
  344. sql = $@"select distinct FCode from maccountdetail a
  345. left join maccountmst b on a.MstID=b.ID
  346. left join machine c on b.MacID=c.ID where 1=1
  347. and b.SDate>'{Convert.ToDateTime(endTime).AddHours(-12).ToString("yyyy-MM-dd HH:mm:ss")}'
  348. and b.SDate<'{endTime}'
  349. and a.typeid=0 and a.fcount>0
  350. and c.FCode like 'AA%'";
  351. var macCodesD = db.FindList<string>(sql);
  352. IEnumerable<Machine> runMacsD = new List<Machine>();
  353. if (macCodesD != null && macCodesD.Count() > 0)
  354. runMacsD = aaMacs.Where(c => macCodesD.Contains(c.FCode));
  355. var uploadHistoriesN = new List<MachineMaterialMst>();
  356. var uploadHistoriesD = new List<MachineMaterialMst>();
  357. if (macCodesN.Any())
  358. {
  359. // 晚班上传文件记录
  360. uploadHistoriesN = (await db.FindListForConditionAsync<MachineMaterialMst>
  361. ($" and a.fdate='{Convert.ToDateTime(startTime).ToString("yyyy-MM-dd")}' and a.shift='N' and a.fdate='{Convert.ToDateTime(startTime).ToString("yyyy-MM-dd")}' and b.FCode in ({string.Join(",", macCodesN.Select(c => $"'{c}'"))})",
  362. ref errorinfo)).ToList();
  363. }
  364. if (macCodesD.Any())
  365. {
  366. uploadHistoriesD = (await db.FindListForConditionAsync<MachineMaterialMst>
  367. ($" and a.fdate='{Convert.ToDateTime(endTime).ToString("yyyy-MM-dd")}' and a.shift='D' and a.fdate='{Convert.ToDateTime(endTime).ToString("yyyy-MM-dd")}' and b.FCode in ({string.Join(",", macCodesD.Select(c => $"'{c}'"))})",
  368. ref errorinfo)).ToList();
  369. }
  370. var notUploadMacsN = new List<Machine>();
  371. var notUploadMacsD = new List<Machine>();
  372. foreach (var item in runMacsN)
  373. {
  374. if (uploadHistoriesN.All(c => c.MacId != item.ID))
  375. {
  376. notUploadMacsN.Add(item);
  377. }
  378. }
  379. foreach (var item in runMacsD)
  380. {
  381. if (uploadHistoriesD.All(c => c.MacId != item.ID))
  382. {
  383. notUploadMacsD.Add(item);
  384. }
  385. }
  386. body.Append($"<h3>{mail.MailBody}</h3>");
  387. body.Append($@"<table style='border-collapse: collapse; border: 1px solid black'>
  388. <tr>
  389. <th style='border: 1px solid black' rowspan='2'>园区</th>
  390. <th style='border: 1px solid black' rowspan='2'>厂房</th>
  391. <th style='border: 1px solid black' rowspan='2'>楼层车间</th>
  392. <th style='border: 1px solid black' rowspan='2'>设备总数</th>
  393. <th style='border: 1px solid black' rowspan='1' colspan='3'>{Convert.ToDateTime(endTime).ToString("MM-dd")}白班</th>
  394. <th style='border: 1px solid black' rowspan='1' colspan='3'>{Convert.ToDateTime(startTime).ToString("MM-dd")}晚班</th>
  395. <th style='border: 1px solid black' rowspan='2'>责任人</th>
  396. </tr>
  397. <tr>
  398. <th style='border: 1px solid black'>稼动设备数</th>
  399. <th style='border: 1px solid black'>未上传机台数</th>
  400. <th style='border: 1px solid black'>未上传率</th>
  401. <th style='border: 1px solid black'>稼动设备数</th>
  402. <th style='border: 1px solid black'>未上传机台数</th>
  403. <th style='border: 1px solid black'>未上传率</th>
  404. </tr>
  405. ");
  406. var notUploadMacs = notUploadMacsD.Concat(notUploadMacsN).Distinct();
  407. var regionChargeDal = new RegionChargerDal(db);
  408. var chargeInfoes = regionChargeDal.Get(string.Empty, string.Empty, string.Empty, string.Empty).Result;
  409. var factoryList = aaMacs.GroupBy(m => m.FactoryName);
  410. foreach (var f in factoryList)
  411. {
  412. var plantGroups = f.GroupBy(c => new { c.PlantName, c.PlantId });
  413. var facCount = f.Select(c => c.FloorId).Distinct().Count();
  414. body.Append("<tr>");
  415. body.Append($@"<td rowspan='{facCount}' style='border: 1px solid black;text-align:center;'>{f.Key}</td>");
  416. for (int i = 0; i < plantGroups.Count(); i++)
  417. {
  418. var plant = plantGroups.ElementAt(i);
  419. var plantCount = plant.Select(c => c.FloorId).Distinct().Count();
  420. body.Append($"<td rowspan='{plantCount}' style='border: 1px solid black;text-align:center;'>{plant.Key.PlantName}</td>");
  421. var floorGroups = plant.GroupBy(c => new { c.Floor, c.FloorId }).OrderBy(c => c.Key.Floor);
  422. for (int j = 0; j < floorGroups.Count(); j++)
  423. {
  424. var floor = floorGroups.ElementAt(j);
  425. var floorTotal = aaMacs.Where(c => c.FloorId == floor.Key.FloorId).Count();
  426. var dayRunCount = runMacsD.Where(c => c.FloorId == floor.Key.FloorId)?.Count() ?? 0;
  427. var nightRunCount = runMacsN.Where(c => c.FloorId == floor.Key.FloorId)?.Count() ?? 0;
  428. var dayErrMacCount = floor.Where(t => notUploadMacsD.Any(c => c.ID == t.ID))?.Count();
  429. var nightErrMacCount = floor.Where(t => notUploadMacsN.Any(c => c.ID == t.ID))?.Count();
  430. double dayPercent = 0, nightPercent = 0;
  431. if (dayRunCount > 0)
  432. {
  433. dayPercent = (double)dayErrMacCount / dayRunCount * 100;
  434. }
  435. if (nightRunCount > 0)
  436. {
  437. nightPercent = (double)nightErrMacCount / nightRunCount * 100;
  438. }
  439. if (j > 0)
  440. {
  441. body.Append("<tr>");
  442. }
  443. body.Append($"<td rowspan='1' style='border: 1px solid black;text-align:center;'>{floor.Key.Floor}</td>");
  444. body.Append($"<td rowspan='1' style='border: 1px solid black;text-align:center;'>{floorTotal}</td>");
  445. body.Append($"<td rowspan='1' style='border: 1px solid black;text-align:center;'>{dayRunCount}</td>");
  446. body.Append($"<td rowspan='1' style='border: 1px solid black;text-align:center;'>{dayErrMacCount}</td>");
  447. if (dayPercent > 50)
  448. {
  449. body.Append($"<td rowspan='1' style='border: 1px solid black;text-align:center;background-color:red;'>{dayPercent.ToString("f2")}%</td>");
  450. }
  451. else
  452. {
  453. body.Append($"<td rowspan='1' style='border: 1px solid black;text-align:center;'>{dayPercent.ToString("f2")}%</td>");
  454. }
  455. body.Append($"<td rowspan='1' style='border: 1px solid black;text-align:center;'>{nightRunCount}</td>");
  456. body.Append($"<td rowspan='1' style='border: 1px solid black;text-align:center;'>{nightErrMacCount}</td>");
  457. if (nightPercent > 50)
  458. {
  459. body.Append($"<td rowspan='1' style='border: 1px solid black;text-align:center;background-color:red;'>{nightPercent.ToString("f2")}%</td>");
  460. }
  461. else
  462. {
  463. body.Append($"<td rowspan='1' style='border: 1px solid black;text-align:center;'>{nightPercent.ToString("f2")}%</td>");
  464. }
  465. var charger = chargeInfoes.data.FirstOrDefault(c => c.Factory == f.Key
  466. && c.Plant == plant.Key.PlantName && c.RegionName == floor.Key.Floor)?.ChargeName;
  467. charger = string.IsNullOrEmpty(charger) ? "--" : charger;
  468. body.Append($"<td rowspan='1' style='border: 1px solid black;text-align:center;'>{charger}</td>");
  469. body.Append($"</tr>");
  470. }
  471. }
  472. }
  473. var noUploadDCount = notUploadMacsD?.Count();
  474. var noUploadNCount = notUploadMacsN?.Count();
  475. double dRate = 0, nRate = 0;
  476. if (runMacsD.Count() > 0)
  477. {
  478. dRate = (double)noUploadDCount / runMacsD.Count();
  479. }
  480. if (runMacsN.Count() > 0)
  481. {
  482. nRate = (double)noUploadNCount / runMacsN.Count();
  483. }
  484. body.Append("<tr>");
  485. body.Append($"<td style='border: 1px solid black;text-align:center;background-color:#40DCFF;' colspan='3'>合计</td>");
  486. body.Append($"<td style='border: 1px solid black;text-align:center;background-color:#40DCFF;' colspan='1'>{aaMacs.Count()}</td>");
  487. body.Append($"<td style='border: 1px solid black;text-align:center;background-color:#40DCFF;' colspan='1'>{runMacsD.Count()}</td>");
  488. body.Append($"<td style='border: 1px solid black;text-align:center;background-color:#40DCFF;' colspan='1'>{noUploadDCount}</td>");
  489. if (dRate > 0.2)
  490. {
  491. body.Append($"<td style='border: 1px solid black;text-align:center;background-color:red;' colspan='1'>{(dRate * 100).ToString("f2")}%</td>");
  492. }
  493. else
  494. {
  495. body.Append($"<td style='border: 1px solid black;text-align:center;#40DCFF;' colspan='1'>{(dRate * 100).ToString("f2")}%</td>");
  496. }
  497. body.Append($"<td style='border: 1px solid black;text-align:center;background-color:#40DCFF;' colspan='1'>{runMacsN.Count()}</td>");
  498. body.Append($"<td style='border: 1px solid black;text-align:center;background-color:#40DCFF;' colspan='1'>{noUploadNCount}</td>");
  499. if (nRate > 0.2)
  500. {
  501. body.Append($"<td style='border: 1px solid black;text-align:center;background-color:red;' colspan='1'>{(nRate * 100).ToString("f2")}%</td>");
  502. }
  503. else
  504. {
  505. body.Append($"<td style='border: 1px solid black;text-align:center;background-color:#40DCFF;' colspan='1'>{(nRate * 100).ToString("f2")}%</td>");
  506. }
  507. body.Append("</td>");
  508. body.Append("</table>");
  509. if (notUploadMacs.Any())
  510. {
  511. var macNumbers = await db.FindListForConditionAsync<MachineNumber>($" and " +
  512. $"a.macid in ({string.Join(",", notUploadMacs.Select(c => c.ID))})", ref errorinfo);
  513. StringBuilder sb = new StringBuilder();
  514. sb.Append($"设备ID,设备编号,设备名称,设备类型,IP地址,实际IP,MAC地址,园区,厂房,楼层,{Convert.ToDateTime(startTime).ToString("MM-dd")}晚班,原因,{Convert.ToDateTime(endTime).ToString("MM-dd")}白班,原因,负责人工号,负责人姓名,");
  515. sb.AppendLine();
  516. notUploadMacs = notUploadMacs.OrderBy(c => c.FactoryName).ThenBy(t => t.PlantName).ThenBy(s => s.Floor)
  517. .ThenBy(h => h.FCode);
  518. foreach (var mac in notUploadMacs)
  519. {
  520. var macnumber = macNumbers.FirstOrDefault(c => c.MacId == mac.ID);
  521. sb.Append($"{mac.FCode},{macnumber?.MacNumber ?? "--"},{mac.FName},{mac.MModeCode},{mac.IPAddress},{(string.IsNullOrEmpty(mac.RealIP) ? "" : mac.RealIP.Replace(",", " | "))},{mac.MacAddress},{mac.FactoryName},{mac.PlantName},{mac.Floor},");
  522. if (notUploadMacsN.Any(c => c.ID == mac.ID))
  523. {
  524. sb.Append($"未传,");
  525. var reason = GetAAMaterialErrorReason(db, mac.FCode, Convert.ToDateTime(endTime), "N");
  526. sb.Append(reason + ",");
  527. }
  528. else
  529. {
  530. sb.Append(",,");
  531. }
  532. if (notUploadMacsD.Any(c => c.ID == mac.ID))
  533. {
  534. sb.Append("未传,");
  535. var reason = GetAAMaterialErrorReason(db, mac.FCode, Convert.ToDateTime(endTime), "D");
  536. sb.Append(reason + ",");
  537. }
  538. else
  539. {
  540. sb.Append(",,");
  541. }
  542. var ccmMac = GetMachineInfoFromCCM(mac.FCode);
  543. if (ccmMac != null)
  544. {
  545. sb.Append(ccmMac.MENo + ",");
  546. sb.Append(ccmMac.MEName + ",");
  547. }
  548. else
  549. {
  550. sb.Append("--,");
  551. sb.Append("--,");
  552. }
  553. sb.AppendLine();
  554. }
  555. MemoryStream stream = new MemoryStream();
  556. StreamWriter write = new StreamWriter(stream, Encoding.UTF8);
  557. write.Write(sb.ToString());
  558. write.Flush();
  559. write.Close();
  560. write.Dispose();
  561. file.Add(new FileAttachment
  562. {
  563. FileContent = stream.ToArray(),
  564. FileName = DateTime.Today.ToString("yyyy-MM-dd") + mail.MailSubject + ".xls",
  565. });
  566. }
  567. }
  568. string errorinfoMail = string.Empty;
  569. myloger.LogError($"AA抛料率预警邮件发送开始");
  570. SendMail(mail.MailServer, mail.MailPort, mail.MailAccount, mail.MailPwd, toMail, ccMail, mail.MailSubject, body.ToString(), ref errorinfoMail, "", file, true);
  571. myloger.LogError($"AA抛料率预警邮件发送结束{errorinfoMail}");
  572. return errorinfoMail;
  573. }
  574. static IEnumerable<MacEntity> list = null;
  575. /// <summary>
  576. /// 获取抛料文件未上传的原因
  577. /// </summary>
  578. /// <param name="db"></param>
  579. /// <param name="macCode"></param>
  580. /// <param name="date"></param>
  581. /// <returns></returns>
  582. private static string GetAAMaterialErrorReason(IDatabase db, string macCode, DateTime date, string shift)
  583. {
  584. string errorinfo = string.Empty;
  585. var states = db.FindListForCondition<OfAppletlog>($" and a.maccode='{macCode}' " +
  586. $"and a.RecTime>'{date.ToString("yyyy-MM-dd 21:00:00")}' " +
  587. $"and a.RecTime<'{date.ToString("yyyy-MM-dd 22:00:00")}'",
  588. ref errorinfo);
  589. if (states != null && states.Any(c => c.AppletS == 1)) // 任意一条小程序开启
  590. {
  591. return "未生成抛料率文件";
  592. }
  593. return "EAP辅助应用未开启";
  594. }
  595. /// <summary>
  596. /// 从CCM获取设备信息
  597. /// </summary>
  598. /// <param name="macCode"></param>
  599. /// <returns></returns>
  600. private static MacEntity GetMachineInfoFromCCM(string macCode)
  601. {
  602. using (IDatabase db = DbFactory.Base("ccmrpt"))
  603. {
  604. var sql = $@"select FACTORY as Factory,LOCATION as Floor,ASSET_NAME as MacName,
  605. ASSET_MODEL as MacModel,ASSET_CODE as AssetCode,EQP_ID as MacCode,DAOCHANG_DATE as EnterDate,
  606. YANSHOU_DATE as CheckDate,YOUXIAO_DATE as ValidDate,ME_NAME as MEName,ME_NO as MENo,WORKSHOP_NAME as WorkShopName,WORKSHOP_NO as WorkShopNo
  607. from ccmrpt.CCMMES_FIXED_ASSETS_V where EQP_ID = '{macCode}'";
  608. var entity = db.FindList<MacEntity>(sql).FirstOrDefault();
  609. return entity;
  610. }
  611. }
  612. /// <summary>
  613. /// 整合实际IP不一致及断线邮件
  614. /// </summary>
  615. /// <returns></returns>
  616. public static async Task<string> IPDifferentAndDiconnectionNotice()
  617. {
  618. string toMail = "";
  619. string ccMail = "";
  620. StringBuilder body = new StringBuilder();
  621. MailSettings mail = null;
  622. List<FileAttachment> file = new List<FileAttachment>();
  623. using (IDatabase db = DbFactory.Base("eapslave"))
  624. {
  625. var dal = new MailSettingsDal(db);
  626. string code = AppConfigurtaionServices.Configuration["IPDifferentNoticeCode"];
  627. mail = dal.GetMailSettingsByCode(code);
  628. if (mail == null)
  629. {
  630. return "邮件代码不存在";
  631. }
  632. List<MailReceiver> receiverList = dal.GetMailReceiverByMailId(mail.ID).ToList();
  633. if (receiverList == null || !receiverList.Any())
  634. {
  635. return "未设置收件人";
  636. }
  637. // receiverList = receiverList.Where(c => c.Name == "韩慧鑫").ToList();
  638. toMail = receiverList.Where(r => r.SendType == 1).Select(r => r.MailAddress).Join(";");
  639. ccMail = receiverList.Where(r => r.SendType == 2).Select(r => r.MailAddress).Join(";");
  640. string disconnCode = AppConfigurtaionServices.Configuration["DisConnNoticeCode"];
  641. var disconnMail = dal.GetMailSettingsByCode(disconnCode);
  642. var disconnMailBody = disconnMail.MailBody;
  643. FileAttachment ipAttachment = null;
  644. //设备查询
  645. try
  646. {
  647. using (IDatabase ccdb = DbFactory.Base("ccmrpt"))
  648. {
  649. var ccdal = new DataCenterDal(ccdb);
  650. string errorinfo = string.Empty;
  651. int total = 0;
  652. list = ccdal.GetMacList(1, 30000, "", "FACTORY", "ASC", out total, ref errorinfo);
  653. }
  654. }
  655. catch (Exception ex)
  656. {
  657. myloger.LogError(ex.ToString());
  658. }
  659. IEnumerable<MacRecipeDto> macStates;
  660. var ipBody = CreateIPDifferentHtml(mail, out ipAttachment, out macStates);
  661. FileAttachment disconnAttachment = null;
  662. var disconnBody = CreateDisconnHtml(mail, macStates, out disconnAttachment);
  663. //var mailBody = mail.MailBody;
  664. //待机程序未开启
  665. // string appletCode = AppConfigurtaionServices.Configuration["AppletCode"];
  666. // var appletMail = dal.GetMailSettingsByCode(appletCode);
  667. FileAttachment appletAttachment = null;
  668. var appletBody = CreateAppletHtml(mail, out appletAttachment);
  669. // var appletMainBody = appletMail.MailBody;
  670. if (string.IsNullOrEmpty(disconnMailBody))
  671. {
  672. disconnMailBody = "<h3>EAP系统异常设备预警</h3>";
  673. //ipBody = $"<h3>{ipMailBody}</h3>" + ipBody;
  674. }
  675. else
  676. {
  677. disconnMailBody = $"<h3>{disconnMailBody}</h3>";
  678. }
  679. //if (string.IsNullOrEmpty(disconnMailBody))
  680. //{
  681. // disconnMailBody = "机台断线信息汇总";
  682. // disconnBody = $"<h3>{disconnMailBody}</h3>" + disconnBody;
  683. //}
  684. //if (string.IsNullOrEmpty(appletMainBody))
  685. //{
  686. // appletMainBody = "待机程序未开启信息汇总";
  687. // appletBody = $"<h3>{appletMainBody}</h3>" + appletBody;
  688. //}
  689. // body.Append("<div style='text-align:center;'>");
  690. body.Append(disconnMailBody).Append(ipBody);
  691. // body.Append("</div>");
  692. //body.Append(ipBody).Append(disconnBody).Append(appletBody);
  693. if (ipAttachment != null)
  694. {
  695. file.Add(ipAttachment);
  696. }
  697. if (disconnAttachment != null)
  698. {
  699. file.Add(disconnAttachment);
  700. }
  701. if (appletAttachment != null)
  702. {
  703. file.Add(appletAttachment);
  704. }
  705. }
  706. string errorinfoMail = "";
  707. myloger.LogError($"机台系统IP与实际IP不一致邮件发送开始");
  708. SendMail(mail.MailServer, mail.MailPort, mail.MailAccount, mail.MailPwd, toMail, ccMail, "EAP系统异常设备预警", body.ToString(), ref errorinfoMail, "", file, true);
  709. myloger.LogError($"机台系统IP与实际IP不一致邮件发送结束{errorinfoMail}");
  710. return errorinfoMail;
  711. }
  712. /// <summary>
  713. /// 生成IP不一致邮件正文和附件
  714. /// </summary>
  715. /// <param name="mail"></param>
  716. /// <param name="attachment"></param>
  717. /// <returns></returns>
  718. //public static string CreateIPDifferentHtml(MailSettings mail, out FileAttachment attachment)
  719. //{
  720. // attachment = null;
  721. // using (IDatabase db = DbFactory.Base("eapslave"))
  722. // {
  723. // var dalMac = new MachineDal(db);
  724. // var macList = dalMac.GetMachineList();
  725. // macList = macList.Where(m => !string.IsNullOrEmpty(m.FactoryName) && !m.FactoryName.Contains("临时区域"));
  726. // var sql = "select a.id from machine a " +
  727. // "left join macstatus01 b on a.fcode=b.maccode " +
  728. // "where b.statusid=204906";
  729. // var body = new StringBuilder();
  730. // var shutDownMacIds = db.FindList<string>(sql)?.Select(c => Convert.ToInt32(c));
  731. // if (macList == null || macList.Count() == 0)
  732. // {
  733. // return "未查询到设备";
  734. // }
  735. // body.Append($"<h3>{mail.MailBody}</h3>");
  736. // body.Append(@"<table cellpadding='3' style='border-collapse: collapse; border: 1px solid black'>
  737. // <tr>
  738. // <th style='border: 1px solid black'>园区</th>
  739. // <th style='border: 1px solid black'>设备类型</th>
  740. // <th style='border: 1px solid black'>总数量</th>
  741. // <th style='border: 1px solid black'>ip不一致数量</th>
  742. // <th style='border: 1px solid black'>ip不一致率</th>
  743. // </tr>");
  744. // var factoryList = macList.GroupBy(m => m.FactoryName);
  745. // foreach (var f in factoryList)
  746. // {
  747. // //每个园区所有机台按机型分组
  748. // var pCodeList = macList.Where(m => m.FactoryName == f.Key).GroupBy(m => m.MModeCode);
  749. // //每个园区ip不一致按机型分组
  750. // var pCodeDisConnList = macList.Where(m => m.FactoryName == f.Key && (string.IsNullOrEmpty(m.RealIP) || !m.RealIP.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).
  751. // Contains(m.IPAddress)) && !shutDownMacIds.Contains(m.ID)).GroupBy(m => m.MModeCode);
  752. // int i = 0;
  753. // int totalCount = 0;
  754. // int disConnTotalCount = 0;
  755. // foreach (var p in pCodeList)
  756. // {
  757. // //每个机型的总数
  758. // int count = p.Count();
  759. // //每个机型离线的总数
  760. // int disConnCount = pCodeDisConnList.Where(m => m.Key == p.Key).Any() ? pCodeDisConnList.Where(m => m.Key == p.Key).First().Count() : 0;
  761. // if (i == 0)
  762. // {
  763. // body.Append($@"<tr><td rowspan='{pCodeList.Count() + 1}' style='border: 1px solid black'>{f.Key}</td>
  764. // <td style='border: 1px solid black'>{p.Key}</td>
  765. // <td style='border: 1px solid black'>{count}</td>
  766. // <td style='border: 1px solid black'>{disConnCount}</td>
  767. // <td style='border: 1px solid black'>{(Convert.ToDouble(disConnCount) * 100 / Convert.ToDouble(count)).ToString("f2")}%</td>
  768. // </tr>");
  769. // }
  770. // else
  771. // {
  772. // body.Append($@"<tr>
  773. // <td style='border: 1px solid black'>{p.Key}</td>
  774. // <td style='border: 1px solid black'>{count}</td>
  775. // <td style='border: 1px solid black'>{disConnCount}</td>
  776. // <td style='border: 1px solid black'>{(Convert.ToDouble(disConnCount) * 100 / Convert.ToDouble(count)).ToString("f2")}%</td>
  777. // </tr>");
  778. // }
  779. // totalCount += count;
  780. // disConnTotalCount += disConnCount;
  781. // i++;
  782. // }
  783. // body.Append($@"<tr><td style='border: 1px solid black'>总计</td>
  784. // <td style='border: 1px solid black'>{totalCount}</td>
  785. // <td style='border: 1px solid black'>{disConnTotalCount}</td>
  786. // <td style='border: 1px solid black'>{(Convert.ToDouble(disConnTotalCount) * 100 / Convert.ToDouble(totalCount)).ToString("f2")}%</td>
  787. // </tr>");
  788. // }
  789. // body.Append("</table>");
  790. // var macListDisConn = macList.Where(m => string.IsNullOrEmpty(m.RealIP) || !m.RealIP.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).
  791. // Contains(m.IPAddress))
  792. // .Where(m => !shutDownMacIds.Contains(m.ID))
  793. // .OrderBy(m => m.FactoryName).OrderBy(m => m.FCode);
  794. // if (macListDisConn.Any())
  795. // {
  796. // StringBuilder sb = new StringBuilder();
  797. // sb.Append("设备ID,设备名称,设备类型,IP地址,实际IP,MAC地址,园区,楼层");
  798. // sb.AppendLine();
  799. // foreach (var mac in macListDisConn)
  800. // {
  801. // sb.Append($"{mac.FCode},{mac.FName},{mac.MModeCode},{mac.IPAddress},{(string.IsNullOrEmpty(mac.RealIP) ? "" : mac.RealIP.Replace(",", " | "))},{mac.MacAddress},{mac.FactoryName},{mac.Floor}");
  802. // sb.AppendLine();
  803. // }
  804. // MemoryStream stream = new MemoryStream();
  805. // StreamWriter write = new StreamWriter(stream, Encoding.UTF8);
  806. // write.Write(sb.ToString());
  807. // write.Flush();
  808. // write.Close();
  809. // write.Dispose();
  810. // attachment = new FileAttachment
  811. // {
  812. // FileContent = stream.ToArray(),
  813. // FileName = DateTime.Today.ToString("yyyy-MM-dd") + mail.MailSubject + ".xls",
  814. // };
  815. // }
  816. // return body.ToString();
  817. // }
  818. //}
  819. static List<string> macs = new List<string>();
  820. #region 后加
  821. /// <summary>
  822. /// 生成IP不一致邮件正文和附件
  823. /// </summary>
  824. /// <param name="mail"></param>
  825. /// <param name="attachment"></param>
  826. /// <returns></returns>
  827. public static string CreateIPDifferentHtml(MailSettings mail, out FileAttachment attachment,
  828. out IEnumerable<MacRecipeDto> macCon)
  829. {
  830. attachment = null;
  831. macCon = null;
  832. try
  833. {
  834. macs = new List<string>();
  835. attachment = null;
  836. using (IDatabase db = DbFactory.Base("eapslave"))
  837. {
  838. var dalOfdisCons = new OfdisconDal(db);
  839. var ofdisCons = dalOfdisCons.GetOfdisconExprort(1000);
  840. var dalMac = new MachineDal(db);
  841. var sql = "select a.id from machine a " +
  842. "left join macstatus01 b on a.fcode=b.maccode " +
  843. "where b.statusid=204906";
  844. var body = new StringBuilder();
  845. var shutDownMacIds = db.FindList<string>(sql)?.Select(c => Convert.ToInt32(c));
  846. var macList = dalMac.GetMachineList().Where(c => c.PCode != "" && c.PCode != "AOI");
  847. macList = macList.Where(m => !string.IsNullOrEmpty(m.FactoryName) && !m.FactoryName.Contains("临时区域") && !m.FactoryName.Contains("闲置") && !m.LineName.Contains("临时区域") && !m.LineName.Contains("闲置"));
  848. string errorinfo = string.Empty;
  849. int total;
  850. var dalConMac = new MacRecipeDal(db);
  851. macCon = dalConMac.GetMacRecipeDtos("", 1, 10000, "MacCode", "asc", out total, ref errorinfo);
  852. macCon = macCon.Where(m => !string.IsNullOrEmpty(m.Factory) && !m.Factory.Contains("临时区域") && !m.Factory.Contains("闲置") && !m.Line.Contains("临时区域") && !m.Line.Contains("闲置") && !shutDownMacIds.Contains(m.MacId) && m.PCode != "AOI");
  853. var factoryList = macList.GroupBy(m => m.FactoryName);
  854. #region 去除都是0的Mac
  855. foreach (var f in factoryList)
  856. {
  857. //每个园区所有机台按厂房分组
  858. var pCodeList = macList.Where(m => m.FactoryName == f.Key).GroupBy(m => m.PlantName);
  859. foreach (var p in pCodeList)
  860. {
  861. // 工序
  862. var pfcodes = macList.Where(m => m.PlantName == p.Key && m.FactoryName == f.Key).GroupBy(m => m.PCode);
  863. //断网
  864. var pCodeDisConnList = macCon.Where(m => m.PlantName == p.Key && m.Factory == f.Key && m.StatusID == 1).GroupBy(m => m.PCode);
  865. //ip不一致按工序分组
  866. var pCodeDisIPList = macList.Where(m => m.FactoryName == f.Key && m.PlantName == p.Key && (string.IsNullOrEmpty(m.RealIP) || !m.RealIP.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).
  867. Contains(m.IPAddress)) && !shutDownMacIds.Contains(m.ID)).GroupBy(m => m.PCode);
  868. // 待机程序未开启
  869. var pCodeNoAppletList = macList.Where(m => m.PlantName == p.Key && m.FactoryName == f.Key && m.AppletS != 1 && !shutDownMacIds.Contains(m.ID)).GroupBy(m => m.PCode);
  870. //工序
  871. foreach (var item in pfcodes)
  872. {
  873. //每个工序的总数
  874. int count = item.Count();
  875. //每个工序离线的总数
  876. int disConnCount = 0;
  877. if (pCodeDisConnList != null)
  878. {
  879. disConnCount = pCodeDisConnList.Where(m => m.Key == item.Key).Any() ? pCodeDisConnList.Where(m => m.Key == item.Key).FirstOrDefault().Count() : 0;
  880. }
  881. //每个工序IP不一致的总数
  882. int disIPCount = pCodeDisIPList.Where(m => m.Key == item.Key).Any() ? pCodeDisIPList.Where(m => m.Key == item.Key).First().Count() : 0;
  883. //每个工序待机程序未开启的总数
  884. int disAppletCount = pCodeNoAppletList.Where(m => m.Key == item.Key).Any() ? pCodeNoAppletList.Where(m => m.Key == item.Key).First().Count() : 0;
  885. double disConnCountRate = Convert.ToDouble(disConnCount) * 100 / Convert.ToDouble(count);
  886. double disIPCountRate = Convert.ToDouble(disIPCount) * 100 / Convert.ToDouble(count);
  887. double disAppletCountRate = Convert.ToDouble(disAppletCount) * 100 / Convert.ToDouble(count);
  888. if (disConnCountRate <= 0 && disIPCountRate <= 0 && disAppletCountRate <= 0)
  889. {
  890. foreach (var mac in item)
  891. {
  892. macs.Add(mac.FCode);
  893. }
  894. }
  895. }
  896. }
  897. }
  898. #endregion
  899. if (macs.Count() > 0)
  900. {
  901. macList = macList.Where(l => !macs.Contains(l.FCode));
  902. }
  903. if (macList == null || macList.Count() == 0)
  904. {
  905. return "未查询到设备";
  906. }
  907. // body.Append($"<h3>{mail.MailBody}</h3>");
  908. body.Append(@"<table cellpadding='3' style='border-collapse: collapse; border: 1px solid black'>
  909. <tr height='19' style='height: 14.25pt'>
  910. <td
  911. class='xl67'
  912. height='51'
  913. width='72'
  914. rowspan='2'
  915. style='text-align: center;white-space: normal;background: #8ea9db;border: 0.5pt solid windowtext;
  916. height: 38.25pt;
  917. width: 54pt;
  918. border-right: 0.5pt solid windowtext;
  919. border-bottom: 0.5pt solid windowtext;
  920. '
  921. x:str=''
  922. >
  923. 园区
  924. </td>
  925. <td
  926. class='xl68'
  927. width='102'
  928. rowspan='2'
  929. style='text-align: center;white-space: normal;background: #8ea9db;border: 0.5pt solid windowtext;
  930. width: 76.5pt;
  931. border-right: 0.5pt solid windowtext;
  932. border-bottom: 0.5pt solid windowtext;
  933. '
  934. x:str=''
  935. >
  936. 厂房
  937. </td>
  938. <td
  939. class='xl68'
  940. width='88'
  941. rowspan='2'
  942. style='text-align: center;white-space: normal;background: #8ea9db;border: 0.5pt solid windowtext;
  943. width: 66pt;
  944. border-right: 0.5pt solid windowtext;
  945. border-bottom: 0.5pt solid windowtext;
  946. '
  947. x:str=''
  948. >
  949. 工序
  950. </td>
  951. <td
  952. class='xl69'
  953. width='74'
  954. rowspan='2'
  955. style='text-align: center;white-space: normal;background: #8ea9db;border-left: 0.5pt solid windowtext;border-top: 0.5pt solid windowtext;border-bottom: 0.5pt solid windowtext;
  956. width: 55.5pt;
  957. border-right: none;
  958. border-bottom: 0.5pt solid windowtext;
  959. '
  960. x:str=''
  961. >
  962. 设备总数
  963. </td>
  964. <td
  965. class='xl70'
  966. width='132'
  967. colspan='2'
  968. style='text-align: center;
  969. background: #a5a5a5;
  970. font-weight: 700;
  971. border-left: 2pt double windowtext;
  972. border-top: 2pt double windowtext;
  973. border-right: 0.5pt solid windowtext;
  974. border-bottom: 0.5pt solid windowtext;
  975. width: 99pt;
  976. border-right: 2pt double windowtext;
  977. border-bottom: 0.5pt solid windowtext;
  978. '
  979. x:str=''
  980. >
  981. 断网预警
  982. </td>
  983. <td
  984. class='xl72'
  985. width='132'
  986. colspan='2'
  987. style='text-align: center;
  988. background: #ffc000;
  989. font-weight: 700;
  990. border-top: 0.5pt solid windowtext;
  991. border-right: 0.5pt solid windowtext;
  992. border-bottom: 0.5pt solid windowtext;
  993. width: 99pt;
  994. border-right: none;
  995. border-bottom: 0.5pt solid windowtext;
  996. '
  997. x:str=''
  998. >
  999. IP不一致
  1000. </td>
  1001. <td
  1002. class='xl98'
  1003. width='139'
  1004. colspan='2'
  1005. style='text-align: center;
  1006. background: #70ad47;
  1007. font-weight: 700;
  1008. border-left: 2pt double windowtext;
  1009. border-top: 2pt double windowtext;
  1010. border-right: 0.5pt solid windowtext;
  1011. border-bottom: 0.5pt solid windowtext;
  1012. width: 104.25pt;
  1013. border-right: 2pt double windowtext;
  1014. border-bottom: 0.5pt solid windowtext;
  1015. '
  1016. x:str=''
  1017. >
  1018. EAP辅助应用开启
  1019. </td>
  1020. <td
  1021. class='xl100'
  1022. width='112'
  1023. rowspan='2'
  1024. style='text-align: center;
  1025. background: #8ea9db;
  1026. border-top: 0.5pt solid windowtext;
  1027. border-right: 0.5pt solid windowtext;
  1028. border-bottom: 0.5pt solid windowtext;
  1029. width: 84pt;
  1030. border-right: 0.5pt solid windowtext;
  1031. border-bottom: 0.5pt solid windowtext;
  1032. '
  1033. x:str=''
  1034. >
  1035. 责任人
  1036. </td>
  1037. </tr>
  1038. <tr height='32' style='height: 24pt'>
  1039. <td class='xl74' style='text-align: center;
  1040. background: #a5a5a5;
  1041. border-left: 2pt double windowtext;
  1042. border-top: 0.5pt solid windowtext;
  1043. border-right: 0.5pt solid windowtext;
  1044. border-bottom: 0.5pt solid windowtext;'>离线数量</td>
  1045. <td class='xl75' style=' text-align: center;
  1046. background: #a5a5a5;
  1047. border-left: 0.5pt solid windowtext;
  1048. border-top: 0.5pt solid windowtext;
  1049. border-right: 2pt double windowtext;
  1050. border-bottom: 0.5pt solid windowtext;'>离线率</td>
  1051. <td class='xl76' style='text-align: center;
  1052. background: #ffc000;
  1053. border-top: 0.5pt solid windowtext;
  1054. border-right: 0.5pt solid windowtext;
  1055. border-bottom: 0.5pt solid windowtext;'>IP异常数</td>
  1056. <td class='xl77' style='text-align: center;
  1057. background: #ffc000;
  1058. border-left: 0.5pt solid windowtext;
  1059. border-top: 0.5pt solid windowtext;
  1060. border-bottom: 0.5pt solid windowtext;'>异常率</td>
  1061. <td class='xl101' style='text-align: center;
  1062. background: #70ad47;
  1063. border-left: 2pt double windowtext;
  1064. border-top: 0.5pt solid windowtext;
  1065. border-right: 0.5pt solid windowtext;
  1066. border-bottom: 0.5pt solid windowtext;'>未启动数</td>
  1067. <td class='xl102' style='text-align: center;
  1068. background: #70ad47;
  1069. border-left: 0.5pt solid windowtext;
  1070. border-top: 0.5pt solid windowtext;
  1071. border-right: 2pt double windowtext;
  1072. border-bottom: 0.5pt solid windowtext;'>未启动率</td>
  1073. </tr>");
  1074. // factoryList = macList.GroupBy(m => m.FactoryName);
  1075. int totalCounts = 0;
  1076. int disConnTotalCounts = 0;
  1077. int disIPTotalCounts = 0;
  1078. int disAppletTotalCounts = 0;
  1079. // var ofDisCon = CurrentDbContext
  1080. // 园区
  1081. foreach (var f in factoryList)
  1082. {
  1083. //每个园区所有机台按厂房分组
  1084. //var pCodeList = macList.Where(m => m.FactoryName == f.Key).GroupBy(m => m.PlantName);
  1085. var pCodeList = f.GroupBy(m => m.PlantName);
  1086. int i = 0;
  1087. int totalCount = 0;
  1088. int disConnTotalCount = 0;
  1089. int disIPTotalCount = 0;
  1090. int disAppletTotalCount = 0;
  1091. int rows = 0;
  1092. //厂房
  1093. foreach (var p in pCodeList)
  1094. {
  1095. var pfcodes = macList.Where(m => m.PlantName == p.Key && m.FactoryName == f.Key).GroupBy(m => m.PCode);
  1096. rows += pfcodes.Count();
  1097. }
  1098. foreach (var p in pCodeList)
  1099. {
  1100. // 工序
  1101. var pfcodes = macList.Where(m => m.PlantName == p.Key && m.FactoryName == f.Key).GroupBy(m => m.PCode);
  1102. //断网
  1103. var pCodeDisConnList = macCon.Where(m => m.PlantName == p.Key && m.Factory == f.Key && m.StatusID == 1).GroupBy(m => m.PCode);
  1104. //ip不一致按工序分组
  1105. var pCodeDisIPList = macList.Where(m => m.FactoryName == f.Key && m.PlantName == p.Key && (string.IsNullOrEmpty(m.RealIP) || !m.RealIP.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).
  1106. Contains(m.IPAddress)) && !shutDownMacIds.Contains(m.ID)).GroupBy(m => m.PCode);
  1107. // 待机程序未开启
  1108. var pCodeNoAppletList = macList.Where(m => m.PlantName == p.Key && m.FactoryName == f.Key && m.AppletS != 1 && !shutDownMacIds.Contains(m.ID)).GroupBy(m => m.PCode);
  1109. int j = 0;
  1110. //工序
  1111. foreach (var item in pfcodes)
  1112. {
  1113. //每个工序的总数
  1114. int count = item.Count();
  1115. //每个工序离线的总数
  1116. int disConnCount = 0;
  1117. if (pCodeDisConnList != null)
  1118. {
  1119. disConnCount = pCodeDisConnList.Where(m => m.Key == item.Key).Any() ? pCodeDisConnList.Where(m => m.Key == item.Key).FirstOrDefault().Count() : 0;
  1120. }
  1121. //每个工序IP不一致的总数
  1122. int disIPCount = pCodeDisIPList.Where(m => m.Key == item.Key).Any() ? pCodeDisIPList.Where(m => m.Key == item.Key).First().Count() : 0;
  1123. //每个工序待机程序未开启的总数
  1124. int disAppletCount = pCodeNoAppletList.Where(m => m.Key == item.Key).Any() ? pCodeNoAppletList.Where(m => m.Key == item.Key).First().Count() : 0;
  1125. double disConnCountRate = Convert.ToDouble(disConnCount) * 100 / Convert.ToDouble(count);
  1126. double disIPCountRate = Convert.ToDouble(disIPCount) * 100 / Convert.ToDouble(count);
  1127. double disAppletCountRate = Convert.ToDouble(disAppletCount) * 100 / Convert.ToDouble(count);
  1128. //if (disConnCountRate <= 0 && disIPCountRate <= 0 && disAppletCountRate <= 0)
  1129. //{
  1130. // continue;
  1131. //}
  1132. string disConn = disConnCountRate >= 9 ? ";background:red" : "";
  1133. string disIP = disIPCountRate >= 9 ? ";background:red" : "";
  1134. string disApplet = disAppletCountRate >= 9 ? ";background:red" : "";
  1135. if (disConnCountRate >= 5)
  1136. {
  1137. disConn += ";font-weight:bold";
  1138. }
  1139. if (disIPCountRate >= 5)
  1140. {
  1141. disIP += ";font-weight:bold";
  1142. }
  1143. if (disAppletCountRate >= 5)
  1144. {
  1145. disApplet += ";font-weight:bold";
  1146. }
  1147. //var charger = chargeInfoes.data.FirstOrDefault(c => c.Factory == f.Key
  1148. //&& c.Plant == p.Key && c.RegionName == floor.Key.Floor)?.ChargeName;
  1149. //charger = string.IsNullOrEmpty(charger) ? "--" : charger;
  1150. if (i == 0)
  1151. {
  1152. body.Append($@"<tr style='text-align: center;'>
  1153. <td rowspan='{rows + pCodeList.Count()}' style='border: 1px solid black'>{f.Key}</td>
  1154. <td rowspan='{ pfcodes.Count()}' style='border: 1px solid black'>{p.Key}</td>
  1155. <td style='border: 1px solid black'>{item.Key}</td>
  1156. <td style='border: 1px solid black'>{count}</td>
  1157. <td style='border: 1px solid black'>{disConnCount}</td>
  1158. <td style='border: 1px solid black{disConn}'>{disConnCountRate.ToString("f2")}%</td>
  1159. <td style='border: 1px solid black'>{disIPCount}</td>
  1160. <td style='border: 1px solid black{disIP}'>{disIPCountRate.ToString("f2")}%</td>
  1161. <td style='border: 1px solid black'>{disAppletCount}</td>
  1162. <td style='border: 1px solid black{disApplet}'>{disAppletCountRate.ToString("f2")}%</td>
  1163. <td style='border: 1px solid black'>{ofdisCons?.Where(l => l.plantid == p.Select(c => c.PlantId).FirstOrDefault() && l.pcode == item.Key).Select(l => l.employs).FirstOrDefault()}</td>
  1164. </tr>");
  1165. }
  1166. else
  1167. {
  1168. if (j == 0)
  1169. {
  1170. body.Append($@"<tr style='text-align: center;'>
  1171. <td rowspan='{ pfcodes.Count()}' style='border: 1px solid black'>{p.Key}</td>
  1172. <td style='border: 1px solid black'>{item.Key}</td>
  1173. <td style='border: 1px solid black'>{count}</td>
  1174. <td style='border: 1px solid black'>{disConnCount}</td>
  1175. <td style='border: 1px solid black{disConn}'>{disConnCountRate.ToString("f2")}%</td>
  1176. <td style='border: 1px solid black'>{disIPCount}</td>
  1177. <td style='border: 1px solid black{disIP}'>{disIPCountRate.ToString("f2")}%</td>
  1178. <td style='border: 1px solid black'>{disAppletCount}</td>
  1179. <td style='border: 1px solid black{disApplet}'>{disAppletCountRate.ToString("f2")}%</td>
  1180. <td style='border: 1px solid black'>{ofdisCons?.Where(l => l.plantid == p.Select(c => c.PlantId).FirstOrDefault() && l.pcode == item.Key).Select(l => l.employs).FirstOrDefault()}</td>
  1181. </tr>");
  1182. }
  1183. else
  1184. {
  1185. body.Append($@"<tr style='text-align: center;'>
  1186. <td style='border: 1px solid black'>{item.Key}</td>
  1187. <td style='border: 1px solid black'>{count}</td>
  1188. <td style='border: 1px solid black'>{disConnCount}</td>
  1189. <td style='border: 1px solid black{disConn}'>{disConnCountRate.ToString("f2")}%</td>
  1190. <td style='border: 1px solid black'>{disIPCount}</td>
  1191. <td style='border: 1px solid black{disIP}'>{disIPCountRate.ToString("f2")}%</td>
  1192. <td style='border: 1px solid black'>{disAppletCount}</td>
  1193. <td style='border: 1px solid black{disApplet}'>{disAppletCountRate.ToString("f2")}%</td>
  1194. <td style='border: 1px solid black'>{ofdisCons?.Where(l => l.plantid == p.Select(c => c.PlantId).FirstOrDefault() && l.pcode == item.Key).Select(l => l.employs).FirstOrDefault()}</td>
  1195. </tr>");
  1196. }
  1197. }
  1198. totalCount += count;
  1199. disConnTotalCount += disConnCount;
  1200. disIPTotalCount += disIPCount;
  1201. disAppletTotalCount += disAppletCount;
  1202. i++;
  1203. j++;
  1204. }
  1205. double disConnTotalRate = Convert.ToDouble(disConnTotalCount) * 100 / Convert.ToDouble(totalCount == 0 ? 1 : totalCount);
  1206. double disIPTotalRate = Convert.ToDouble(disIPTotalCount) * 100 / Convert.ToDouble(totalCount == 0 ? 1 : totalCount);
  1207. double disAppletTotalRate = Convert.ToDouble(disAppletTotalCount) * 100 / Convert.ToDouble(totalCount == 0 ? 1 : totalCount);
  1208. //if (disConnTotalRate <= 0 && disIPTotalRate <= 0 && disAppletTotalRate <= 0)
  1209. //{
  1210. // continue;
  1211. //}
  1212. string disConnTotalRateStyle = disConnTotalRate >= 10 ? ";background:red;font-weight:bold;font-size: 18px;" : "";
  1213. string disIPTotalRateStyle = disIPTotalRate >= 10 ? ";background:red;font-weight:bold;font-size: 16px;" : "";
  1214. string disAppletTotalRateStyle = disAppletTotalRate >= 10 ? ";background:red;font-weight:bold;font-size: 18px;" : "";
  1215. //厂房合计
  1216. body.Append($@"<tr style='text-align: center;'>
  1217. <td style='border: 1px solid black;background: #fce4d6;' colspan='2'>{p.Key}合计</td>
  1218. <td style='border: 1px solid black;background: #fce4d6;'>{totalCount}</td>
  1219. <td style='border: 1px solid black;background: #fce4d6;'>{disConnTotalCount}</td>
  1220. <td style='border: 1px solid black;background: #fce4d6;{disConnTotalRateStyle}'>{disConnTotalRate.ToString("f2")}%</td>
  1221. <td style='border: 1px solid black;background: #fce4d6;'>{disIPTotalCount}</td>
  1222. <td style='border: 1px solid black;background: #fce4d6;{disIPTotalRateStyle}'>{disIPTotalRate.ToString("f2")}%</td>
  1223. <td style='border: 1px solid black;background: #fce4d6;'>{disAppletTotalCount}</td>
  1224. <td style='border: 1px solid black;background: #fce4d6;{disAppletTotalRateStyle}'>{disAppletTotalRate.ToString("f2")}%</td>
  1225. <td style='border: 1px solid black'>{ofdisCons?.Where(l => l.plantid == p.Select(c => c.PlantId).FirstOrDefault() && l.pcode is null).Select(l => l.employs).FirstOrDefault()}</td>
  1226. </tr>");
  1227. j = 0;
  1228. totalCounts += totalCount;
  1229. disConnTotalCounts += disConnTotalCount;
  1230. disIPTotalCounts += disIPTotalCount;
  1231. disAppletTotalCounts += disAppletTotalCount;
  1232. totalCount = 0;
  1233. disConnTotalCount = 0;
  1234. disIPTotalCount = 0;
  1235. disAppletTotalCount = 0;
  1236. }
  1237. i = 0;
  1238. }
  1239. double disConnTotalRates = Convert.ToDouble(disConnTotalCounts) * 100 / Convert.ToDouble(totalCounts);
  1240. double disIPTotalRates = Convert.ToDouble(disIPTotalCounts) * 100 / Convert.ToDouble(totalCounts);
  1241. double disAppletTotalRates = Convert.ToDouble(disAppletTotalCounts) * 100 / Convert.ToDouble(totalCounts);
  1242. string disConnTotalRatesStyle = disConnTotalRates >= 10 ? ";background:red;font-weight:bold;font-size: 18px;" : "";
  1243. string disIPTotalRatesStyle = disIPTotalRates >= 10 ? ";background:red;font-weight:bold;font-size: 18px;" : "";
  1244. string disAppletTotalRatesStyle = disAppletTotalRates >= 10 ? ";background:red;font-weight:bold;font-size: 16px;" : "";
  1245. body.Append($@"<tr height='19' style='height: 14.25pt'>
  1246. <td
  1247. class='xl92'
  1248. height='19'
  1249. colspan='3'
  1250. style='text-align: center;
  1251. background: #ffff00;
  1252. border: 0.5pt solid windowtext;
  1253. height: 14.25pt;
  1254. border-right: 0.5pt solid windowtext;
  1255. border-bottom: 0.5pt solid windowtext;
  1256. '
  1257. >
  1258. 总计
  1259. </td>
  1260. <td class='xl93' style='text-align: center;
  1261. background: #ffff00;
  1262. border-left: 0.5pt solid windowtext;
  1263. border-top: 0.5pt solid windowtext;
  1264. border-bottom: 0.5pt solid windowtext;'>{macList.Count()}</td>
  1265. <td class='xl94' style='text-align: center;
  1266. background: #ffff00;
  1267. border-left: 2pt double windowtext;
  1268. border-top: 0.5pt solid windowtext;
  1269. border-right: 0.5pt solid windowtext;
  1270. border-bottom: 2pt double windowtext;'>{disConnTotalCounts}</td>
  1271. <td class='xl95' style=' text-align: center;
  1272. background: #ffff00;
  1273. border-left: 0.5pt solid windowtext;
  1274. border-top: 0.5pt solid windowtext;
  1275. border-right: 2pt double windowtext;
  1276. border-bottom: 2pt double windowtext;{disConnTotalRatesStyle}'>{disConnTotalRates.ToString("f2")}%</td>
  1277. <td class='xl96' style='text-align: center;
  1278. background: #ffff00;
  1279. border-top: 0.5pt solid windowtext;
  1280. border-right: 0.5pt solid windowtext;
  1281. border-bottom: 0.5pt solid windowtext;'>{disIPTotalCounts}</td>
  1282. <td class='xl93' style=' text-align: center;
  1283. background: #ffff00;
  1284. border-left: 0.5pt solid windowtext;
  1285. border-top: 0.5pt solid windowtext;
  1286. border-bottom: 0.5pt solid windowtext;{disIPTotalRatesStyle}'>{disIPTotalRates.ToString("f2")}%</td>
  1287. <td class='xl94' style=' text-align: center;
  1288. background: #ffff00;
  1289. border-left: 2pt double windowtext;
  1290. border-top: 0.5pt solid windowtext;
  1291. border-right: 0.5pt solid windowtext;
  1292. border-bottom: 2pt double windowtext;'>{disAppletTotalCounts}</td>
  1293. <td class='xl95' style='text-align: center;
  1294. background: #ffff00;
  1295. border-left: 0.5pt solid windowtext;
  1296. border-top: 0.5pt solid windowtext;
  1297. border-right: 2pt double windowtext;
  1298. border-bottom: 2pt double windowtext;{disAppletTotalRatesStyle}'>{disAppletTotalRates.ToString("f2")}%</td>
  1299. <td class='xl88' style='text-align: center;
  1300. border-top: 0.5pt solid windowtext;
  1301. border-right: 0.5pt solid windowtext;
  1302. border-bottom: 0.5pt solid windowtext; '></td>
  1303. </tr>");
  1304. body.Append("</table>");
  1305. var macListDisConn = macList.Where(m => string.IsNullOrEmpty(m.RealIP) || !m.RealIP.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).
  1306. Contains(m.IPAddress))
  1307. .Where(m => !shutDownMacIds.Contains(m.ID))
  1308. .OrderBy(m => m.FactoryName).OrderBy(m => m.FCode);
  1309. if (macListDisConn.Any())
  1310. {
  1311. var macNumbers = db.FindListForCondition<MachineNumber>($" ", ref errorinfo);
  1312. StringBuilder sb = new StringBuilder();
  1313. sb.Append("设备ID,设备编号,设备名称,设备类型,IP地址,实际IP,MAC地址,园区,厂房,楼层,线体,责任人");
  1314. sb.AppendLine();
  1315. foreach (var mac in macListDisConn)
  1316. {
  1317. var macnumber = macNumbers.FirstOrDefault(c => c.MacId == mac.ID);
  1318. sb.Append($"{mac.FCode},{macnumber?.MacNumber ?? "--"},{mac.FName},{mac.MModeCode},{mac.IPAddress},{(string.IsNullOrEmpty(mac.RealIP) ? "" : mac.RealIP.Replace(",", " | "))},{mac.MacAddress},{mac.FactoryName},{mac.PlantName},{mac.Floor},{mac.LineName},{list?.Where(l => l.MacCode == mac.FCode.TrimEnd('L').TrimEnd('l').TrimEnd('r').TrimEnd('R')).Select(l => l.MEName).FirstOrDefault()}");
  1319. sb.AppendLine();
  1320. }
  1321. myloger.LogError("ip不一致" + sb.ToString());
  1322. MemoryStream stream = new MemoryStream();
  1323. StreamWriter write = new StreamWriter(stream, Encoding.UTF8);
  1324. write.Write(sb.ToString());
  1325. write.Flush();
  1326. write.Close();
  1327. write.Dispose();
  1328. attachment = new FileAttachment
  1329. {
  1330. FileContent = stream.ToArray(),
  1331. FileName = DateTime.Today.ToString("yyyy-MM-dd") + "各园区ASM设备IP异常清单" + ".xls",
  1332. };
  1333. }
  1334. myloger.LogError("表格" + body.ToString());
  1335. return body.ToString();
  1336. }
  1337. }
  1338. catch (Exception ex)
  1339. {
  1340. myloger.LogError(ex.ToString());
  1341. return "";
  1342. }
  1343. }
  1344. #endregion
  1345. public static string CreateAppletHtml(MailSettings mail, out FileAttachment attachment)
  1346. {
  1347. attachment = null;
  1348. using (IDatabase db = DbFactory.Base("eapslave"))
  1349. {
  1350. var dalMac = new MachineDal(db);
  1351. var sql = "select a.id from machine a " +
  1352. "left join macstatus01 b on a.fcode=b.maccode " +
  1353. "where b.statusid=204906";
  1354. var shutDownMacIds = db.FindList<string>(sql)?.Select(c => Convert.ToInt32(c));
  1355. var macList = dalMac.GetMachineList();
  1356. macList = macList.Where(m => !macs.Contains(m.FCode) && !string.IsNullOrEmpty(m.FactoryName) &&
  1357. !m.FactoryName.Contains("临时区域") && !m.FactoryName.Contains("闲置")
  1358. && !m.LineName.Contains("临时区域") && !m.LineName.Contains("闲置") && !shutDownMacIds.Contains(m.ID));
  1359. var body = new StringBuilder();
  1360. if (macList == null || macList.Count() == 0)
  1361. {
  1362. return "未查询到设备";
  1363. }
  1364. body.Append($"<h3></h3>");
  1365. body.Append(@"<table cellpadding='3' style='border-collapse: collapse; border: 1px solid black'>
  1366. <tr>
  1367. <th style='border: 1px solid black'>园区</th>
  1368. <th style='border: 1px solid black'>设备类型</th>
  1369. <th style='border: 1px solid black'>总数量</th>
  1370. <th style='border: 1px solid black'>待机程序未开启数量</th>
  1371. <th style='border: 1px solid black'>未开启率</th>
  1372. </tr>");
  1373. var factoryList = macList.GroupBy(m => m.FactoryName);
  1374. foreach (var f in factoryList)
  1375. {
  1376. //每个园区所有机台按机型分组
  1377. var pCodeList = macList.Where(m => m.FactoryName == f.Key).GroupBy(m => m.MModeCode);
  1378. //每个园区ip不一致按机型分组
  1379. var pCodeDisConnList = macList.Where(m => m.FactoryName == f.Key && m.AppletS != 1 && !shutDownMacIds.Contains(m.ID)).GroupBy(m => m.MModeCode);
  1380. int i = 0;
  1381. int totalCount = 0;
  1382. int disConnTotalCount = 0;
  1383. foreach (var p in pCodeList)
  1384. {
  1385. //每个机型的总数
  1386. int count = p.Count();
  1387. //每个机型未开启的总数
  1388. int disConnCount = pCodeDisConnList.Where(m => m.Key == p.Key).Any() ? pCodeDisConnList.Where(m => m.Key == p.Key).First().Count() : 0;
  1389. if (i == 0)
  1390. {
  1391. body.Append($@"<tr><td rowspan='{pCodeList.Count() + 1}' style='border: 1px solid black'>{f.Key}</td>
  1392. <td style='border: 1px solid black'>{p.Key}</td>
  1393. <td style='border: 1px solid black'>{count}</td>
  1394. <td style='border: 1px solid black'>{disConnCount}</td>
  1395. <td style='border: 1px solid black'>{(Convert.ToDouble(disConnCount) * 100 / Convert.ToDouble(count)).ToString("f2")}%</td>
  1396. </tr>");
  1397. }
  1398. else
  1399. {
  1400. body.Append($@"<tr>
  1401. <td style='border: 1px solid black'>{p.Key}</td>
  1402. <td style='border: 1px solid black'>{count}</td>
  1403. <td style='border: 1px solid black'>{disConnCount}</td>
  1404. <td style='border: 1px solid black'>{(Convert.ToDouble(disConnCount) * 100 / Convert.ToDouble(count)).ToString("f2")}%</td>
  1405. </tr>");
  1406. }
  1407. totalCount += count;
  1408. disConnTotalCount += disConnCount;
  1409. i++;
  1410. }
  1411. body.Append($@"<tr><td style='border: 1px solid black'>总计</td>
  1412. <td style='border: 1px solid black'>{totalCount}</td>
  1413. <td style='border: 1px solid black'>{disConnTotalCount}</td>
  1414. <td style='border: 1px solid black'>{(Convert.ToDouble(disConnTotalCount) * 100 / Convert.ToDouble(totalCount)).ToString("f2")}%</td>
  1415. </tr>");
  1416. }
  1417. body.Append("</table>");
  1418. var macListDisConn = macList.Where(m => m.AppletS != 1)
  1419. .OrderBy(m => m.FactoryName).OrderBy(m => m.FCode);
  1420. if (macListDisConn.Any())
  1421. {
  1422. string errorinfo = "";
  1423. var macNumbers = db.FindListForCondition<MachineNumber>($"", ref errorinfo);
  1424. StringBuilder sb = new StringBuilder();
  1425. sb.Append("设备ID,设备编号,设备名称,设备类型,IP地址,实际IP,MAC地址,园区,厂房,楼层,线体,责任人");
  1426. sb.AppendLine();
  1427. foreach (var mac in macListDisConn)
  1428. {
  1429. var macnumber = macNumbers.FirstOrDefault(c => c.MacId == mac.ID);
  1430. sb.Append($"{mac.FCode},{macnumber?.MacNumber ?? "--"},{mac.FName},{mac.MModeCode},{mac.IPAddress},{(string.IsNullOrEmpty(mac.RealIP) ? "" : mac.RealIP.Replace(",", " | "))},{mac.MacAddress},{mac.FactoryName},{mac.PlantName},{mac.Floor},{mac.LineName},{list?.Where(l => l.MacCode == mac.FCode.TrimEnd('L').TrimEnd('l').TrimEnd('r').TrimEnd('R')).Select(l => l.MEName).FirstOrDefault()}");
  1431. sb.AppendLine();
  1432. }
  1433. myloger.LogError("待机程序未开启" + sb.ToString());
  1434. MemoryStream stream = new MemoryStream();
  1435. StreamWriter write = new StreamWriter(stream, Encoding.UTF8);
  1436. write.Write(sb.ToString());
  1437. write.Flush();
  1438. write.Close();
  1439. write.Dispose();
  1440. attachment = new FileAttachment
  1441. {
  1442. FileContent = stream.ToArray(),
  1443. FileName = DateTime.Today.ToString("yyyy-MM-dd") + "各园区ASM设备EAP辅助应用未开启清单" + ".xls",
  1444. };
  1445. }
  1446. return body.ToString();
  1447. }
  1448. }
  1449. public static string CreateDisconnHtml(MailSettings mail, IEnumerable<MacRecipeDto> macList, out FileAttachment attachment)
  1450. {
  1451. attachment = null;
  1452. var body = new StringBuilder();
  1453. using (IDatabase db = DbFactory.Base("eapslave"))
  1454. {
  1455. var dalMac = new MacRecipeDal(db);
  1456. string errorinfo = string.Empty;
  1457. int total;
  1458. var sql = "select a.id from machine a " +
  1459. "left join macstatus01 b on a.fcode=b.maccode " +
  1460. "where b.statusid=204906";
  1461. var shutDownMacIds = db.FindList<string>(sql)?.Select(c => Convert.ToInt32(c));
  1462. // var macList = dalMac.GetMacRecipeDtos("", 1, 10000, "MacCode", "asc", out total, ref errorinfo);
  1463. macList = macList.Where(m => !macs.Contains(m.MacCode) && !string.IsNullOrEmpty(m.Factory)
  1464. && !m.Factory.Contains("临时区域") && !m.Factory.Contains("闲置") &&
  1465. !m.Line.Contains("临时区域") && !m.Line.Contains("闲置") &&
  1466. !shutDownMacIds.Contains(m.MacId) && m.PCode != "AOI");
  1467. if (macList == null || macList.Count() == 0)
  1468. {
  1469. return "未查询到设备";
  1470. }
  1471. body.Append($"<h3></h3>");
  1472. //body.Append($"<h3>{DateTime.Today.AddDays(-1).ToString("yyyy-MM-dd")}</h3>");
  1473. body.Append(@"<table cellpadding='3' style='border-collapse: collapse; border: 1px solid black'>
  1474. <tr>
  1475. <th style='border: 1px solid black'>园区</th>
  1476. <th style='border: 1px solid black'>设备类型</th>
  1477. <th style='border: 1px solid black'>总数量</th>
  1478. <th style='border: 1px solid black'>离线数量</th>
  1479. <th style='border: 1px solid black'>离线率</th>
  1480. </tr>");
  1481. var factoryList = macList.GroupBy(m => m.Factory);
  1482. var regionChargeDal = new RegionChargerDal(db);
  1483. var chargeInfoes = regionChargeDal.Get(string.Empty, string.Empty, string.Empty, string.Empty).Result;
  1484. foreach (var f in factoryList)
  1485. {
  1486. //每个园区所有状态按机型分组
  1487. var pCodeList = macList.Where(m => m.Factory == f.Key).GroupBy(m => m.PCode);
  1488. //每个园区离线状态按机型分组
  1489. var pCodeDisConnList = macList.Where(m => m.Factory == f.Key && m.StatusID == 1).GroupBy(m => m.PCode);
  1490. int i = 0;
  1491. int totalCount = 0;
  1492. int disConnTotalCount = 0;
  1493. foreach (var p in pCodeList)
  1494. {
  1495. //每个机型的总数
  1496. int count = p.Count();
  1497. //每个机型离线的总数
  1498. int disConnCount = pCodeDisConnList.Where(m => m.Key == p.Key).Any() ? pCodeDisConnList.Where(m => m.Key == p.Key).First().Count() : 0;
  1499. if (i == 0)
  1500. {
  1501. body.Append($@"<tr><td rowspan='{pCodeList.Count() + 1}' style='border: 1px solid black'>{f.Key}</td>
  1502. <td style='border: 1px solid black'>{p.Key}</td>
  1503. <td style='border: 1px solid black'>{count}</td>
  1504. <td style='border: 1px solid black'>{disConnCount}</td>
  1505. <td style='border: 1px solid black'>{(Convert.ToDouble(disConnCount) * 100 / Convert.ToDouble(count)).ToString("f2")}%</td>
  1506. </tr>");
  1507. }
  1508. else
  1509. {
  1510. body.Append($@"<tr>
  1511. <td style='border: 1px solid black'>{p.Key}</td>
  1512. <td style='border: 1px solid black'>{count}</td>
  1513. <td style='border: 1px solid black'>{disConnCount}</td>
  1514. <td style='border: 1px solid black'>{(Convert.ToDouble(disConnCount) * 100 / Convert.ToDouble(count)).ToString("f2")}%</td>
  1515. </tr>");
  1516. }
  1517. totalCount += count;
  1518. disConnTotalCount += disConnCount;
  1519. i++;
  1520. }
  1521. body.Append($@"<tr><td style='border: 1px solid black'>总计</td>
  1522. <td style='border: 1px solid black'>{totalCount}</td>
  1523. <td style='border: 1px solid black'>{disConnTotalCount}</td>
  1524. <td style='border: 1px solid black'>{(Convert.ToDouble(disConnTotalCount) * 100 / Convert.ToDouble(totalCount)).ToString("f2")}%</td>
  1525. </tr>");
  1526. }
  1527. body.Append("</table>");
  1528. var macListDisConn = macList.Where(m => !string.IsNullOrEmpty(m.Factory) && m.StatusID == 1).OrderBy(m => m.Factory).OrderBy(m => m.MacCode);
  1529. if (macListDisConn.Any())
  1530. {
  1531. var macNumbers = db.FindListForCondition<MachineNumber>($"", ref errorinfo);
  1532. StringBuilder sb = new StringBuilder();
  1533. sb.Append("设备ID,设备编号,设备类型,当前IP,MAC地址,园区,厂房,楼层,线体,最新程序名称,连接状态,责任人");
  1534. sb.AppendLine();
  1535. foreach (var mac in macListDisConn)
  1536. {
  1537. var macnumber = macNumbers.FirstOrDefault(c => c.MacId == mac.MacId);
  1538. sb.Append($"{mac.MacCode},{macnumber?.MacNumber ?? "--"},{mac.PCode},{(string.IsNullOrEmpty(mac.RealIp) ? "" : mac.RealIp.Replace(",", " | "))},{mac.MacAddress},{mac.Factory},{mac.PlantName},{mac.Floor},{mac.Line},{mac.ProgramName},{mac.StatusName},{list?.Where(l => l.MacCode == mac.MacCode.TrimEnd('L').TrimEnd('l').TrimEnd('r').TrimEnd('R')).Select(l => l.MEName).FirstOrDefault()}");
  1539. sb.AppendLine();
  1540. }
  1541. myloger.LogError("离线" + sb.ToString());
  1542. MemoryStream stream = new MemoryStream();
  1543. StreamWriter write = new StreamWriter(stream, Encoding.UTF8);
  1544. write.Write(sb.ToString());
  1545. write.Flush();
  1546. write.Close();
  1547. write.Dispose();
  1548. attachment = new FileAttachment
  1549. {
  1550. FileContent = stream.ToArray(),
  1551. FileName = DateTime.Today.ToString("yyyy-MM-dd") + mail.MailSubject + ".xls",
  1552. };
  1553. }
  1554. }
  1555. return body.ToString();
  1556. }
  1557. /// <summary>
  1558. /// 发送邮件方法
  1559. /// </summary>
  1560. /// <param name="FromMial">发件人邮箱</param>
  1561. /// <param name="ToMial">收件人邮箱(多个收件人地址用";"号隔开)</param>
  1562. /// <param name="AuthorizationCode">发件人授权码</param>
  1563. /// <param name="ReplyTo">对方回复邮件时默认的接收地址(不设置也是可以的)</param>
  1564. /// <param name="CCMial">//邮件的抄送者(多个抄送人用";"号隔开)</param>
  1565. /// <param name="File_Path">附件的地址</param>
  1566. public static void SendMail(string mailServer, string port, string fromMail, string password, string toMail, string ccMial, string subject, string body, ref string errorinfo, string file_Path = "", List<FileAttachment> fileAttachments = null, bool isBodyHtml = false)
  1567. {
  1568. try
  1569. {
  1570. //实例化一个发送邮件类。
  1571. MailMessage mailMessage = new MailMessage();
  1572. //邮件的优先级,分为 Low, Normal, High,通常用 Normal即可
  1573. mailMessage.Priority = MailPriority.Normal;
  1574. //发件人邮箱地址。
  1575. mailMessage.From = new MailAddress(fromMail);
  1576. //收件人邮箱地址。需要群发就写多个
  1577. //拆分邮箱地址
  1578. List<string> ToMiallist = toMail.Split(';').ToList();
  1579. for (int i = 0; i < ToMiallist.Count; i++)
  1580. {
  1581. mailMessage.To.Add(new MailAddress(ToMiallist[i])); //收件人邮箱地址。
  1582. }
  1583. if (ccMial != "" && ccMial != null)
  1584. {
  1585. List<string> CCMiallist = ccMial.Split(';').ToList();
  1586. for (int i = 0; i < CCMiallist.Count; i++)
  1587. {
  1588. //邮件的抄送者,支持群发
  1589. mailMessage.CC.Add(new MailAddress(CCMiallist[i]));
  1590. }
  1591. }
  1592. //如果你的邮件标题包含中文,这里一定要指定,否则对方收到的极有可能是乱码。
  1593. mailMessage.SubjectEncoding = Encoding.UTF8;
  1594. //邮件正文是否是HTML格式
  1595. mailMessage.IsBodyHtml = isBodyHtml;
  1596. //邮件标题。
  1597. mailMessage.Subject = subject;
  1598. mailMessage.SubjectEncoding = Encoding.UTF8;
  1599. //邮件内容。
  1600. mailMessage.Body = body;
  1601. //设置邮件的附件,将在客户端选择的附件先上传到服务器保存一个,然后加入到mail中
  1602. if (file_Path != "" && file_Path != null)
  1603. {
  1604. //将附件添加到邮件
  1605. mailMessage.Attachments.Add(new System.Net.Mail.Attachment(file_Path));
  1606. //获取或设置此电子邮件的发送通知。
  1607. mailMessage.DeliveryNotificationOptions = DeliveryNotificationOptions.OnSuccess;
  1608. }
  1609. if (fileAttachments != null && fileAttachments.Count > 0)
  1610. {
  1611. foreach (var fileAttachment in fileAttachments)
  1612. {
  1613. mailMessage.Attachments.Add(new System.Net.Mail.Attachment(new MemoryStream(fileAttachment.FileContent),
  1614. fileAttachment.FileName));
  1615. }
  1616. }
  1617. //实例化一个SmtpClient类。
  1618. SmtpClient client = new SmtpClient();
  1619. client.DeliveryMethod = SmtpDeliveryMethod.Network;//指定电子邮件发送方式
  1620. client.Host = mailServer;
  1621. client.Port = string.IsNullOrEmpty(port) ? 25 : Convert.ToInt32(port);
  1622. #region 设置邮件服务器地址
  1623. //在这里我使用的是163邮箱,所以是smtp.163.com,如果你使用的是qq邮箱,那么就是smtp.qq.com。
  1624. // client.Host = "smtp.163.com";
  1625. //if (fromMail.Length != 0)
  1626. //{
  1627. // //根据发件人的邮件地址判断发件服务器地址 默认端口一般是25
  1628. // string[] addressor = fromMail.Trim().Split(new Char[] { '@', '.' });
  1629. // switch (addressor[1])
  1630. // {
  1631. // case "163":
  1632. // client.Host = "smtp.163.com";
  1633. // break;
  1634. // case "126":
  1635. // client.Host = "smtp.126.com";
  1636. // break;
  1637. // case "qq":
  1638. // client.Host = "smtp.qq.com";
  1639. // break;
  1640. // case "gmail":
  1641. // client.Host = "smtp.gmail.com";
  1642. // break;
  1643. // case "hotmail":
  1644. // client.Host = "smtp.live.com";//outlook邮箱
  1645. // //client.Port = 587;
  1646. // break;
  1647. // case "foxmail":
  1648. // client.Host = "smtp.foxmail.com";
  1649. // break;
  1650. // case "sina":
  1651. // client.Host = "smtp.sina.com.cn";
  1652. // break;
  1653. // default:
  1654. // client.Host = "smtp.exmail.qq.com";//qq企业邮箱
  1655. // break;
  1656. // }
  1657. //}
  1658. #endregion
  1659. //使用安全加密连接。
  1660. //client.EnableSsl = true;
  1661. //不和请求一块发送。
  1662. client.UseDefaultCredentials = false;
  1663. //验证发件人身份(发件人的邮箱,邮箱里的生成授权码);
  1664. client.Credentials = new NetworkCredential(fromMail, password);
  1665. //如果发送失败,SMTP 服务器将发送 失败邮件告诉我
  1666. //mailMessage.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;
  1667. //发送
  1668. client.Send(mailMessage);
  1669. //mailMessage.Attachments.Dispose();//释放资源,必须,否则会锁附件文件
  1670. }
  1671. catch (Exception ex)
  1672. {
  1673. errorinfo = "发送失败:" + ex.Message + ";" + (ex.InnerException != null ? ex.InnerException.Message : "");
  1674. }
  1675. }
  1676. public static void SendByMailKit(string mailServer, string port, string fromMail, string password, string toMail, string ccMial, string subject, string body, ref string errorinfo, List<FileAttachment> fileAttachments = null)
  1677. {
  1678. try
  1679. {
  1680. var message = new MimeKit.MimeMessage();
  1681. message.From.Add(new MimeKit.MailboxAddress("from", fromMail));
  1682. List<string> toMaillist = toMail.Split(';').ToList();
  1683. for (int i = 0; i < toMaillist.Count; i++)
  1684. {
  1685. message.To.Add(new MimeKit.MailboxAddress("to", toMaillist[i])); //收件人邮箱地址。
  1686. }
  1687. if (ccMial != "" && ccMial != null)
  1688. {
  1689. List<string> ccMaillist = ccMial.Split(';').ToList();
  1690. for (int i = 0; i < ccMaillist.Count; i++)
  1691. {
  1692. //邮件的抄送者,支持群发
  1693. message.Cc.Add(new MimeKit.MailboxAddress("cc", ccMaillist[i]));
  1694. }
  1695. }
  1696. message.Subject = subject;
  1697. //var plain = new MimeKit.TextPart("plain")
  1698. //{
  1699. // Text = @"不好意思,我在测试程序,Sorry!"
  1700. //};
  1701. var html = new MimeKit.TextPart("html")
  1702. {
  1703. Text = body
  1704. };
  1705. var alternative = new MimeKit.Multipart("alternative");
  1706. //alternative.Add(plain);
  1707. alternative.Add(html);
  1708. // now create the multipart/mixed container to hold the message text and the
  1709. // image attachment
  1710. var multipart = new MimeKit.Multipart("mixed");
  1711. multipart.Add(alternative);
  1712. if (fileAttachments != null && fileAttachments.Count > 0)
  1713. {
  1714. foreach (var fileAttachment in fileAttachments)
  1715. {
  1716. // create an image attachment for the file located at path
  1717. var attachment = new MimeKit.MimePart("application", "ms-excel")
  1718. {
  1719. Content = new MimeKit.MimeContent(fileAttachment.Stream, MimeKit.ContentEncoding.Default),
  1720. ContentDisposition = new MimeKit.ContentDisposition(MimeKit.ContentDisposition.Attachment),
  1721. ContentTransferEncoding = MimeKit.ContentEncoding.Base64,
  1722. FileName = fileAttachment.FileName
  1723. };
  1724. multipart.Add(attachment);
  1725. }
  1726. }
  1727. message.Body = multipart;
  1728. using (var client = new MailKit.Net.Smtp.SmtpClient())
  1729. {
  1730. client.CheckCertificateRevocation = false;
  1731. client.Connect(mailServer, Convert.ToInt32(port), false);
  1732. // Note: since we don't have an OAuth2 token, disable
  1733. // the XOAUTH2 authentication mechanism.
  1734. client.AuthenticationMechanisms.Remove("XOAUTH2");
  1735. // Note: only needed if the SMTP server requires authentication
  1736. client.Authenticate(fromMail, password);
  1737. client.Send(message);
  1738. client.Disconnect(true);
  1739. }
  1740. }
  1741. catch (Exception ex)
  1742. {
  1743. errorinfo = "发送失败:" + ex.Message + ";" + (ex.InnerException != null ? ex.InnerException.Message : "");
  1744. }
  1745. }
  1746. }
  1747. public class FileAttachment
  1748. {
  1749. public String FileName { get; set; }
  1750. public byte[] FileContent { get; set; }
  1751. public Stream Stream { get; set; }
  1752. }
  1753. }