大约在2013年旁边就做过类似的功能,利用的也是标准的POP3邮件发送协议,实在便是tcp通信,按照标准协议解析和应答,然后将邮件内容和附件一起发出去,最开始做的很粗糙,后面随着真实项目的运用需求不断变革,该组件也在不断的迭代发展,比如多线程发送邮件,多个收件人,多个附件,html格式的邮件内容。这个富文本格式的邮件内容,可以直接将报警信息组合成表格形式的内容,这样用户连附件都不用打开,直接内容便是table表格的形式,用起来其实方便。
本系统支持邮件转发,条件是对应的邮箱账号须要开通 POP3/SMTP 等做事,按照图示开启即可,一样平常开启后会设置独立的管理密码,记得在系统设置那边的邮件转发,填写密码的时候要填的是独立管理密码,而不是邮箱号的密码,这个机制和任何第三方邮箱管理软件都一样。
五、干系代码
void SendEmailThread::run(){ while (!stopped) { int count = contents.count(); if (count > 0) { mutex.lock(); QString content = contents.takeFirst(); QString fileName = fileNames.takeFirst(); mutex.unlock(); QString result; QStringList list = sendEmailAddr.split("@"); QString tempSMTP = list.at(1).split(".").at(0); int tempPort = 25; //***邮箱端口号为465,必须启用SSL协议. if (tempSMTP.toUpper() == "***") { tempPort = 465; } SmtpClient smtp(QString("smtp.%1.com").arg(tempSMTP), tempPort, tempPort == 25 ? SmtpClient::TcpConnection : SmtpClient::SslConnection); smtp.setUser(sendEmailAddr); smtp.setPassword(sendEmailPwd); //构建邮件主题,包含发件人收件人附件等. MimeMessage message; message.setSender(new EmailAddress(sendEmailAddr)); //逐个添加收件人 QStringList receiver = receiveEmailAddr.split(';'); for (int i = 0; i < receiver.size(); ++i) { message.addRecipient(new EmailAddress(receiver.at(i))); } //构建邮件标题 message.setSubject(emialTitle); //构建邮件正文 MimeHtml text; text.setHtml(content); message.addPart(&text); //构建附件-报警图像 if (fileName.length() > 0) { QStringList attas = fileName.split(";"); foreach (QString tempAtta, attas) { QFile file = new QFile(tempAtta); if (file->exists()) { message.addPart(new MimeAttachment(file)); } } } if (!smtp.connectToHost()) { result = "邮件做事器连接失落败"; } else { if (!smtp.login()) { result = "邮件用户登录失落败"; } else { if (!smtp.sendMail(message)) { result = "邮件发送失落败"; } else { result = "邮件发送成功"; } } } smtp.quit(); if (!result.isEmpty()) { emit receiveEmailResult(result); } msleep(1000); } msleep(100); } stopped = false;}void SendServer::checkEmail(){ int count = listEmail.count(); if (count == 0) { return; } //邮件内容,无论多长都可以拼在一起发送,<br>用来换行显示 QStringList listContent, listFileName; for (int i = 0; i < count; ++i) { QString str = listEmail.takeFirst(); if (str.contains("|")) { QStringList list = str.split("|"); QString content = list.at(0); QString fileName = list.at(1); if (!content.isEmpty()) { listContent << content; } if (!fileName.isEmpty()) { listFileName << fileName; } } else { listContent.append(str); } } //构建html字符串 QStringList html; if (listContent.count() > 0) { //将字符串转换为表格形式,先取出字段名,然后取出内容 //位号: AT-40002 掌握器: 1#调度室掌握器 探测器: 2#阀站CO 触发值: 78.7 %LEL 类型: 浓度上限报警 韶光: 2019-02-24 21:01:30<br> //位号: AT-40003 掌握器: 1#调度室掌握器 探测器: 3#阀站CO 触发值: 57 %VOL 类型: 浓度下限报警 韶光: 2019-02-24 21:01:30<br> //位号: AT-40004 掌握器: 1#调度室掌握器 探测器: 4#阀站CO 触发值: 88 PPM 类型: 浓度下限报警 韶光: 2019-02-24 21:01:30 //先取出字段名 QString str = listContent.first(); QStringList list = str.split(" "); QStringList columnNames; foreach (QString str, list) { columnNames << str.split(": ").first(); } //字段宽度 QList<int> columnWidth; columnWidth << 150 << 200 << 180 << 130 << 160 << 200; //再遍历取出所有数据 QList<QStringList> rowContents; foreach (QString str, listContent) { QStringList list = str.split(" "); QStringList rowContent; foreach (QString temp, list) { rowContent << temp.split(": ").last(); } rowContents << rowContent; } //表格开始 html.append("<table border='1' cellspacing='0' cellpadding='3'>"); //标题字段名称 QString title; for (int i = 0; i < columnNames.count(); ++i) { title += QString("<td width='%1' bgcolor='lightgray' align='center' style='vertical-align:middle;'>%2</td>") .arg(columnWidth.at(i)).arg(columnNames.at(i)); } html.append(QString("<tr>%1</tr>").arg(title)); //内容 for (int j = 0; j < rowContents.count(); j++) { QString row; QStringList rowContent = rowContents.at(j); for (int i = 0; i < rowContent.count(); ++i) { row += QString("<td width='%1' align='center' style='vertical-align:middle;'>%2</td>") .arg(columnWidth.at(i)).arg(rowContent.at(i)); } html.append(QString("<tr>%1</tr>").arg(row)); } //表格结束 html.append("</table>"); } //将邮件内容和附件链接追加到发送报警邮件线程中 SendEmailThread::Instance()->setSendEmailAddr(AppConfig::SendEmailAddr); SendEmailThread::Instance()->setSendEmailPwd(AppConfig::SendEmailPwd); SendEmailThread::Instance()->setReceiveEmailAddr(AppConfig::ReceiveEmailAddr); SendEmailThread::Instance()->append(html.join(""), listFileName.join(";")); //SendEmailThread::Instance()->append(listContent.join("<br>"), listFileName.join(";"));}
