diff --git a/pom.xml b/pom.xml index d5a93af12..c2ac96e3c 100644 --- a/pom.xml +++ b/pom.xml @@ -412,5 +412,10 @@ redisson 3.15.0 + + org.apache.commons + commons-email + 1.5 + diff --git a/src/main/java/com/rebuild/core/support/ConfigurationItem.java b/src/main/java/com/rebuild/core/support/ConfigurationItem.java index 3a08a5414..3ca97be3d 100644 --- a/src/main/java/com/rebuild/core/support/ConfigurationItem.java +++ b/src/main/java/com/rebuild/core/support/ConfigurationItem.java @@ -33,6 +33,7 @@ public enum ConfigurationItem { // 邮件 MailUser, MailPassword, MailAddr, MailName(AppName), + MailSmtpServer, // 短信 SmsUser, SmsPassword, SmsSign(AppName), diff --git a/src/main/java/com/rebuild/core/support/RebuildConfiguration.java b/src/main/java/com/rebuild/core/support/RebuildConfiguration.java index 9a7772ce9..09f57a717 100644 --- a/src/main/java/com/rebuild/core/support/RebuildConfiguration.java +++ b/src/main/java/com/rebuild/core/support/RebuildConfiguration.java @@ -107,11 +107,17 @@ public class RebuildConfiguration extends KVStorage { /** * 邮件账号 * - * @return returns [MailUser, MailPassword, MailAddr, MailName] + * @return returns [MailUser, MailPassword, MailAddr, MailName, MailSmtpServer] */ public static String[] getMailAccount() { - return getsNoUnset(false, + String[] set = getsNoUnset(false, ConfigurationItem.MailUser, ConfigurationItem.MailPassword, ConfigurationItem.MailAddr, ConfigurationItem.MailName); + if (set == null) return null; + + String smtpServer = get(ConfigurationItem.MailSmtpServer); + return new String[] { + set[0], set[1], set[2], set[3], StringUtils.defaultIfBlank(smtpServer, null) + }; } /** diff --git a/src/main/java/com/rebuild/core/support/integration/SMSender.java b/src/main/java/com/rebuild/core/support/integration/SMSender.java index 4568d7151..0630ef835 100644 --- a/src/main/java/com/rebuild/core/support/integration/SMSender.java +++ b/src/main/java/com/rebuild/core/support/integration/SMSender.java @@ -25,6 +25,8 @@ import com.rebuild.utils.CommonsUtils; import com.rebuild.utils.HttpUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; +import org.apache.commons.mail.EmailException; +import org.apache.commons.mail.HtmlEmail; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; @@ -34,7 +36,7 @@ import java.util.HashMap; import java.util.Map; /** - * SUBMAIL SMS/MAIL 发送类 + * SUBMAIL SMS/MAIL 发送 * * @author devezhao * @since 01/03/2019 @@ -44,6 +46,9 @@ public class SMSender { private static final String STATUS_OK = "success"; + private static final int TYPE_SMS = 1; + private static final int TYPE_EMAIL = 2; + /** * @param to * @param subject @@ -84,13 +89,7 @@ public class SMSender { throw new ConfigurationException(Language.L("SomeAccountConfError", "Email")); } - Map params = new HashMap<>(); - params.put("appid", specAccount[0]); - params.put("signature", specAccount[1]); - params.put("to", to); - params.put("from", specAccount[2]); - params.put("from_name", specAccount[3]); - params.put("subject", subject); + // 使用邮件模板 if (useTemplate) { Element mailbody = getMailTemplate(); @@ -101,9 +100,34 @@ public class SMSender { htmlContent = htmlContent.replace("%TO%", to); htmlContent = htmlContent.replace("%TIME%", CalendarUtils.getUTCDateTimeFormat().format(CalendarUtils.now())); htmlContent = htmlContent.replace("%APPNAME%", RebuildConfiguration.get(ConfigurationItem.AppName)); - - params.put("html", htmlContent); content = htmlContent; + } + + final String logContent = "【" + subject + "】" + content; + + // Use SMTP + if (specAccount.length >= 5 && specAccount[4] != null) { + String emailId; + try { + emailId = sendMailViaSmtp(to, subject, content, specAccount); + } catch (EmailException ex) { + log.error("Mail failed to send : " + to + " > " + subject, ex); + return null; + } + + createLog(to, logContent, TYPE_EMAIL, emailId, null); + return emailId; + } + + Map params = new HashMap<>(); + params.put("appid", specAccount[0]); + params.put("signature", specAccount[1]); + params.put("to", to); + params.put("from", specAccount[2]); + params.put("from_name", specAccount[3]); + params.put("subject", subject); + if (useTemplate) { + params.put("html", content); } else { params.put("text", content); } @@ -118,22 +142,45 @@ public class SMSender { return null; } - final String scontent = "【" + subject + "】" + content; - JSONArray returns = rJson.getJSONArray("return"); if (STATUS_OK.equalsIgnoreCase(rJson.getString("status")) && !returns.isEmpty()) { String sendId = ((JSONObject) returns.get(0)).getString("send_id"); - createLog(to, scontent, 2, sendId, null); + createLog(to, logContent, TYPE_EMAIL, sendId, null); return sendId; } else { log.error("Mail failed to send : " + to + " > " + subject + "\nError : " + rJson); - - createLog(to, scontent, 2, null, rJson.getString("msg")); + createLog(to, logContent, TYPE_EMAIL, null, rJson.getString("msg")); return null; } } + /** + * SMTP 发送 + * + * @param to + * @param subject + * @param htmlContent + * @param specAccount + * @return + * @throws ConfigurationException + */ + private static String sendMailViaSmtp(String to, String subject, String htmlContent, String[] specAccount) throws EmailException { + HtmlEmail email = new HtmlEmail(); + email.addTo(to); + email.setSubject(subject); + email.setHtmlMsg(htmlContent); + + email.setAuthentication(specAccount[0], specAccount[1]); + email.setFrom(specAccount[2], specAccount[3]); + + String[] hostPort = specAccount[4].split(":"); + email.setHostName(hostPort[0]); + if (hostPort.length > 1) email.setSmtpPort(Integer.parseInt(hostPort[1])); + + return email.send(); + } + private static Element MT_CACHE = null; /** * @return @@ -216,19 +263,18 @@ public class SMSender { if (STATUS_OK.equalsIgnoreCase(rJson.getString("status"))) { String sendId = rJson.getString("send_id"); - createLog(to, content, 1, sendId, null); + createLog(to, content, TYPE_SMS, sendId, null); return sendId; } else { log.error("SMS failed to send : " + to + " > " + content + "\nError : " + rJson); - - createLog(to, content, 1, null, rJson.getString("msg")); + createLog(to, content, TYPE_SMS, null, rJson.getString("msg")); return null; } } /** - * 发送日志 + * 记录发送日志 * * @param to * @param content diff --git a/src/main/java/com/rebuild/web/admin/ConfigurationController.java b/src/main/java/com/rebuild/web/admin/ConfigurationController.java index 90e965a17..cfe2ad5c7 100644 --- a/src/main/java/com/rebuild/web/admin/ConfigurationController.java +++ b/src/main/java/com/rebuild/web/admin/ConfigurationController.java @@ -201,7 +201,8 @@ public class ConfigurationController extends BaseController { String[] specAccount = new String[]{ data.getString("MailUser"), data.getString("MailPassword"), - data.getString("MailAddr"), data.getString("MailName") + data.getString("MailAddr"), data.getString("MailName"), + data.getString("MailSmtpServer") }; if (specAccount[1].contains("******")) { specAccount[1] = RebuildConfiguration.get(ConfigurationItem.MailPassword); diff --git a/src/main/resources/i18n/language.en.json b/src/main/resources/i18n/language.en.json index 4603641ff..847a9df2e 100644 --- a/src/main/resources/i18n/language.en.json +++ b/src/main/resources/i18n/language.en.json @@ -408,7 +408,6 @@ "GeneralSet": "General", "Integration": "Integration", "IntegrationStorage": "Cloud Storage", - "IntegrationMsgs": "SMS & EMail", "BizAndEntity": "Business Entity", "SomeManage": "{0} Management", "DataImport": "Data Import", @@ -456,7 +455,7 @@ "HelpDoc": "Documentation", "TechSupport": "Tech support", "DefaultLanguage": "Default language", - "SmsEmail": "SMS & EMail", + "SmsEmail": "EMail & SMS", "Submail": "SUBMAIL", "Qiniu": "QINIU", "SomeService": "{0} Service", @@ -1323,6 +1322,11 @@ "SortByModified": "Recently Modified", "SortByCreated": "Recently Created", "SortByCreatedAsc": "Earliest Created", + "SmtpServer": "SMTP Server Address", + "SmtpUser": "SMTP User", + "SmtpPassword": "SMTP Password", + "SwitchEmailSmtp": "Use SMTP", + "SwitchEmailSubmail": "Use SUBMAIL", "s.__": "STATE", "s.ApprovalState.DRAFT": "Draft", diff --git a/src/main/resources/i18n/language.zh_CN.json b/src/main/resources/i18n/language.zh_CN.json index 15b8dd758..630c95ec9 100644 --- a/src/main/resources/i18n/language.zh_CN.json +++ b/src/main/resources/i18n/language.zh_CN.json @@ -408,7 +408,6 @@ "GeneralSet": "通用配置", "Integration": "服务集成", "IntegrationStorage": "云存储", - "IntegrationMsgs": "短信 & 邮件", "BizAndEntity": "业务实体", "SomeManage": "{0}管理", "DataImport": "数据导入", @@ -456,9 +455,9 @@ "HelpDoc": "帮助文档", "TechSupport": "技术支持", "DefaultLanguage": "默认语言", - "SmsEmail": "短信 & 邮件", + "SmsEmail": "邮件 & 短信", "Submail": "赛邮 SUBMAIL", - "Qiniu": "七牛 QINIU", + "Qiniu": "七牛云 QINIU", "SomeService": "{0}服务", "MailServName": "发件人名称", "MailServAddr": "发件人地址", @@ -1323,6 +1322,11 @@ "SortByModified": "最近修改", "SortByCreated": "最近创建", "SortByCreatedAsc": "最早创建", + "SmtpServer": "SMTP 服务器地址", + "SmtpUser": "SMTP 用户名", + "SmtpPassword": "SMTP 密码", + "SwitchEmailSmtp": "使用 SMTP", + "SwitchEmailSubmail": "使用赛邮", "s.__": "状态", "s.ApprovalState.DRAFT": "草稿", diff --git a/src/main/resources/i18n/language.zh_TW.json b/src/main/resources/i18n/language.zh_TW.json index 8e0535938..5aa0bd093 100644 --- a/src/main/resources/i18n/language.zh_TW.json +++ b/src/main/resources/i18n/language.zh_TW.json @@ -408,7 +408,6 @@ "GeneralSet": "通用配寘", "Integration": "服務集成", "IntegrationStorage": "雲存儲", - "IntegrationMsgs": "簡訊 & 郵件", "BizAndEntity": "業務實體", "SomeManage": "{0}管理", "DataImport": "數據導入", @@ -456,9 +455,9 @@ "HelpDoc": "幫助文檔", "TechSupport": "技術支援", "DefaultLanguage": "默認語言", - "SmsEmail": "簡訊&郵件", - "Submail": "賽郵SUBMAIL", - "Qiniu": "七牛QINIU", + "SmsEmail": "郵件 & 簡訊", + "Submail": "賽郵 SUBMAIL", + "Qiniu": "七牛云 QINIU", "SomeService": "{0}服務", "MailServName": "發件人名稱", "MailServAddr": "發件人地址", @@ -1323,6 +1322,11 @@ "SortByModified": "最近修改", "SortByCreated": "最近創建", "SortByCreatedAsc": "最早創建", + "SmtpServer": "SMTP 服務器地址", + "SmtpUser": "SMTP 用戶名", + "SmtpPassword": "SMTP 密碼", + "SwitchEmailSmtp": "使用 SMTP", + "SwitchEmailSubmail": "使用賽郵", "s.__": "狀態", "s.ApprovalState.DRAFT": "草稿", diff --git a/src/main/resources/web/_include/nav-left-admin.html b/src/main/resources/web/_include/nav-left-admin.html index fca19ec12..548a1f70c 100644 --- a/src/main/resources/web/_include/nav-left-admin.html +++ b/src/main/resources/web/_include/nav-left-admin.html @@ -19,7 +19,7 @@ diff --git a/src/main/resources/web/admin/integration/storage-qiniu.html b/src/main/resources/web/admin/integration/storage-qiniu.html index b699ec09d..309d6e599 100644 --- a/src/main/resources/web/admin/integration/storage-qiniu.html +++ b/src/main/resources/web/admin/integration/storage-qiniu.html @@ -15,11 +15,11 @@
- [[${bundle.L('Qiniu')}]] + [[${bundle.L('CloudStorage')}]] [[${bundle.L('Modify')}]]
-
[[${bundle.L('CloudStorage')}]]
+
[[${bundle.L('Qiniu')}]]
diff --git a/src/main/resources/web/admin/integration/submail.html b/src/main/resources/web/admin/integration/submail.html index 2277c6c45..45ecd132f 100644 --- a/src/main/resources/web/admin/integration/submail.html +++ b/src/main/resources/web/admin/integration/submail.html @@ -14,6 +14,16 @@ .row.stats .col-4 { height: 48px; } + .smtp .smtp-hide, + .smtp-show { + display: none; + } + .smtp .smtp-show { + display: inline-block; + } + .smtp tr.smtp-show { + display: table-row; + } @@ -30,46 +40,33 @@ [[${bundle.L('Modify')}]]
-
[[${bundle.L('SomeService,Sms')}]]
-
- - - - - - - - - - - - - - - - - - -
APPID[[${smsAccount == null ? bundle.L('Unset') : smsAccount[0]}]]
APPKEY[[${smsAccount == null ? bundle.L('Unset') : smsAccount[1]}]]
[[${bundle.L('SmsSign')}]][[${smsAccount == null ? bundle.L('Unset') : smsAccount[2]}]]
-
-
-
[[${bundle.L('SomeServiceUnsetTips,Sms')}]]
-
[[${bundle.L('SomeService,Mail')}]]
- +
+ + + + - + - + @@ -79,14 +76,43 @@ - + -
+
[[${bundle.L('SomeServiceUnsetTips,Mail')}]]
+
[[${bundle.L('SomeService,Sms')}]]
+ + + + + + + + + + + + + + + + + + + +
APPID[[${smsAccount == null ? bundle.L('Unset') : smsAccount[0]}]]
APPKEY[[${smsAccount == null ? bundle.L('Unset') : smsAccount[1]}]]
[[${bundle.L('SmsSign')}]][[${smsAccount == null ? bundle.L('Unset') : smsAccount[2]}]]
+
+
+
[[${bundle.L('SomeServiceUnsetTips,Sms')}]]
+