private void bwSendMail_DoWork(object sender, DoWorkEventArgs e) { /* 处理逻辑 * 1.检查附件是否都存在 * 2.发送 * 3.写sqlite、数据库 */ MailSendArgument arg = (MailSendArgument)e.Argument; // 根据模式筛选product ProductList productListTmp = arg.ProductList; try { Manager.SendMail(productListTmp, arg.Date, sender as BackgroundWorker, e, arg.SendInterval); e.Result = arg.IsCredit; // 是否信用(简略) } catch (Exception ex) { throw new Exception(ex.Message); } }
/// <summary> /// 读取产品列表 /// </summary> /// <returns></returns> public static ProductList ReadProductlist() { ProductList productList = new ProductList(); try { using (SQLiteConnection cn = new SQLiteConnection(ConfigurationManager.AppSettings["conn"])) { cn.Open(); string query = "select * from Product"; using (SQLiteCommand cmd = new SQLiteCommand(query, cn)) { using (SQLiteDataReader dr = cmd.ExecuteReader()) { while (dr.Read()) { // 获取产品基本信息 int id = int.Parse(dr["ID"].ToString()); string productName = dr["ProductName"].ToString(); string mailTitle = dr["MailTitle"].ToString(); string mailContent = dr["MailContent"].ToString(); bool disable = bool.Parse(dr["Disable"].ToString()); bool isCredit = bool.Parse(dr["IsCredit"].ToString()); // 2018-12-20是否信用 bool isDelay = bool.Parse(dr["IsDelay"].ToString()); // 2019-03-20发送前延迟是否单独设置 int? delaySeconds = null; // 2019-03-20发送前延迟秒数 if (Convert.IsDBNull(dr["DelaySeconds"])) { delaySeconds = null; } else { delaySeconds = int.Parse(dr["DelaySeconds"].ToString()); } // 获取附件列表 ProductAttachmentList attList = ReadProductAttachmentList(id, cn); // 获取收件人列表 ProductReceiverList receiverList = ReadProductReceiver(id, cn); Product product = new Product( id: id, productName: productName, mailTitle: mailTitle, mailContent: mailContent, disable: disable, attachmentList: attList, receiverList: receiverList, isCredit: isCredit, isDelay: isDelay, delaySeconds: delaySeconds); productList.Add(product); } //eof while } //eof dr } //eof cmd } //eof conn } catch (Exception ex) { throw new Exception(ex.Message); } return(productList); }
// 发送整个list的邮件 public void SendMail(ProductList productList, DateTime date, BackgroundWorker bgWorker, DoWorkEventArgs e, int sendInterval) { // 循环每一个产品 foreach (Product product in productList) { if (true == bgWorker.CancellationPending) // 取消事件 { e.Cancel = true; return; } // 0.打标记 product.IsRunning = true; bgWorker.ReportProgress(1); Thread.Sleep(40); // 20190315增加:发送产品前等待时间,防止QQ邮箱550错误 // 20190320修改:产品可以单独设置等待时间 int timeToWait = sendInterval; // 默认使用全局 if (product.IsDelay) // 如果单个产品有要求 { timeToWait = product.DelaySeconds.Value; } while (timeToWait > 0) { product.Note = string.Format(@"发送前等待{0}秒...", timeToWait); bgWorker.ReportProgress(1); Thread.Sleep(1000); timeToWait--; // 取消事件快速响应 if (true == bgWorker.CancellationPending) // 取消事件 { product.Note = string.Format(@"手工取消..."); bgWorker.ReportProgress(1); e.Cancel = true; return; } } if (product.Disable == true) { string err = "禁用, 跳过"; product.Note = err; product.IsRunning = false; bgWorker.ReportProgress(1); ProductSendLogStorage.AddSendLog(new ProductSendLog(0, product.Id, string.Empty, date, false, err, DateTime.Now)); Thread.Sleep(40); continue; } #region 1.参数校验 // 判断附件是否有设置 if (product.ProductAttachmentList.Count <= 0) { string err = "没有设置任何附件, 不发送"; product.IsRunning = false; product.IsAttachmentOK = false; product.IsSendOK = false; product.Note = err; ProductSendLogStorage.AddSendLog(new ProductSendLog(0, product.Id, string.Empty, date, false, err, DateTime.Now)); bgWorker.ReportProgress(1); continue; } // 判断收件人是否有设置 int iReceiverCnt = 0; foreach (ProductReceiver receiver in product.ProductReceiverList) { if (receiver.ReceiverType == ReceiverType.收件人) { iReceiverCnt++; } } if (iReceiverCnt <= 0) { string err = "没有设置收件人, 不发送"; product.IsRunning = false; product.IsSendOK = false; product.Note = err; ProductSendLogStorage.AddSendLog(new ProductSendLog(0, product.Id, string.Empty, date, false, err, DateTime.Now)); bgWorker.ReportProgress(1); continue; } #endregion #region 2.下载附件 product.Note = "正在下载附件..."; bgWorker.ReportProgress(1); // 创建临时目录(后需要删文件) string tmpFile = Path.Combine(System.Environment.CurrentDirectory, "tmp"); if (!Directory.Exists(tmpFile)) { Directory.CreateDirectory(tmpFile); } // 循环配置下载每一个附件 List <ProductAttachmentTmp> tmpAttList = new List <ProductAttachmentTmp>(); // 临时文件列表 try { foreach (ProductAttachment att in product.ProductAttachmentList) { string displayPath = Util.ReplaceStringWithDateFormat(att.DisplayPath, date); string actualPath = string.Empty; bool isExist = false; switch (att.Type) { case AttachmentType.磁盘路径: actualPath = displayPath; break; case AttachmentType.FTP: actualPath = Path.Combine(tmpFile, Path.GetFileName(displayPath)); // ftp下载 MailFtp ftpInfo = MailFtpStorage.ReadMailFtp(att.FtpID.Value); DownloadFtpFile(displayPath, actualPath, ftpInfo); break; } if (!File.Exists(actualPath)) { isExist = false; } else { isExist = true; } tmpAttList.Add(new ProductAttachmentTmp(displayPath, actualPath, isExist)); } } catch (Exception ex) { // note处写异常 string err = string.Format(@"下载附件失败: {0}", ex.Message); product.IsRunning = false; product.IsAttachmentOK = false; product.IsSendOK = false; product.Note = err; ProductSendLogStorage.AddSendLog(new ProductSendLog(0, product.Id, string.Empty, date, false, err, DateTime.Now)); bgWorker.ReportProgress(1); continue; } // 判断附件缺失 List <string> missingAttachments = new List <string>(); // 缺失文件列表 foreach (ProductAttachmentTmp tmpAttr in tmpAttList) //要改 { if (tmpAttr.IsExist == false) { missingAttachments.Add(tmpAttr.DisplayPath); } } if (missingAttachments.Count > 0) { product.IsRunning = false; product.IsAttachmentOK = false; product.IsSendOK = false; StringBuilder sbAttachments = new StringBuilder(); foreach (string att in missingAttachments) { if (sbAttachments.Length > 0) { sbAttachments.Append(";"); } sbAttachments.Append(att); } string err = "附件缺失: " + sbAttachments.ToString(); product.Note = err; // 写日志 ProductSendLogStorage.AddSendLog(new ProductSendLog(0, product.Id, string.Empty, date, false, err, DateTime.Now)); bgWorker.ReportProgress(1); continue; } else { product.Note = "附件下载完成"; product.IsAttachmentOK = true; product.Note = string.Empty; // 可以具体一点 bgWorker.ReportProgress(1); } Thread.Sleep(40); #endregion #region 3.开始发送邮件 // SmtpClient对象 SmtpClient client = new SmtpClient(); client.Host = MailSender.Host; // smtp服务器 client.Port = MailSender.Port; // smtp端口 client.EnableSsl = MailSender.EnableSSL; // ssl加密 client.Credentials = new System.Net.NetworkCredential(MailSender.Address, MailSender.Password); client.Timeout = MailSender.Timeout * 1000; // 超时时间 // msg对象 MailMessage msg = new MailMessage(); msg.From = new MailAddress(MailSender.Address, MailSender.DisplayName, Encoding.UTF8); // 发件人信息 msg.Subject = Util.ReplaceStringWithDateFormat(product.MailTitle, date); // 邮件标题 msg.SubjectEncoding = System.Text.Encoding.UTF8; // 邮件标题编码 msg.Body = Util.ReplaceStringWithDateFormat(product.MailContent + MailSender.TailContent, date); //邮件内容 msg.BodyEncoding = System.Text.Encoding.UTF8; // 邮件内容编码 msg.IsBodyHtml = false; // 是否是HTML邮件 msg.Priority = MailSender.Priority; // 邮件优先级 // 添加收件人 foreach (ProductReceiver receiver in product.ProductReceiverList) { switch (receiver.ReceiverType) { case ReceiverType.收件人: msg.To.Add(receiver.EmailAddress); break; case ReceiverType.抄送: msg.CC.Add(receiver.EmailAddress); break; case ReceiverType.密送: msg.Bcc.Add(receiver.EmailAddress); break; default: msg.To.Add(receiver.EmailAddress); break; } } // 添加附件 foreach (ProductAttachmentTmp attTmp in tmpAttList) { msg.Attachments.Add(new Attachment(attTmp.ActualPath)); } try { product.Note = "正在发送..."; bgWorker.ReportProgress(1); ServicePointManager.ServerCertificateValidationCallback = delegate(Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { return(true); }; client.Send(msg); //client.SendAsync(msg, userState); product.IsSendOK = true; product.Note = "发送完成"; bgWorker.ReportProgress(1); ProductSendLogStorage.AddSendLog(new ProductSendLog(0, product.Id, string.Empty, date, true, "发送完成", DateTime.Now)); } catch (Exception ex) { product.IsRunning = false; product.IsSendOK = false; product.Note = "发送失败:" + ex.Message; // 可以具体一点 // 写日志 bgWorker.ReportProgress(1); ProductSendLogStorage.AddSendLog(new ProductSendLog(0, product.Id, string.Empty, date, false, "发送失败:" + ex.Message, DateTime.Now)); continue; } finally { if (msg != null) { msg.Dispose(); } } #endregion // 3.发完更新数据库时间戳,写日志 // 4.收尾 product.IsRunning = false; bgWorker.ReportProgress(1); } // 删除tmp目录 try { string tmpFile = Path.Combine(System.Environment.CurrentDirectory, "tmp"); if (Directory.Exists(tmpFile)) { Directory.Delete(tmpFile, true); } } catch (Exception) { } }
private void btnSendAll_Click(object sender, EventArgs e) { if (!bwSendMail.IsBusy) { // 获取参数对象 MailSendMode sendMode = ((ComboBoxSendModeItem)cbSendMode.SelectedItem).Value; DateTime date; if (rbDateToday.Checked) { date = DateTime.Now.Date; } else { date = dtpDate.Value.Date; } ProductList productListTmp = new ProductList(); switch (sendMode) { case MailSendMode.重发所有产品: foreach (Product product in Manager.ProductList) { product.Note = string.Empty; productListTmp.Add(product); } break; case MailSendMode.只发送勾选的产品: foreach (ListViewItem lvi in lvProductList.Items) { if (lvi.Checked == true) { productListTmp.Add((Product)lvi.Tag); } } break; case MailSendMode.发送未发送的产品: default: foreach (Product product in Manager.ProductList) { if (product.IsSendOK == false) { productListTmp.Add(product); } product.Note = string.Empty; } break; } MailSendArgument arg = new MailSendArgument(sendMode, date, productListTmp, false, Manager.MailSender.SendInterval); lbIsAllSendOK.Text = "N/A"; lbIsAllSendOK.ForeColor = Color.Black; btnSendAll.Text = "点击取消..."; // 禁用菜单 menuStrip.Enabled = false; btnSendAllNoCredit.Enabled = false; bwSendMail.RunWorkerAsync(arg); } else { btnSendAll.Text = "发送邮件"; bwSendMail.CancelAsync(); } }
public void ReloadProductList() { _productList = ProductStorage.ReadProductlist(); // 读取产品信息 }