在做Winform項目的時候,一直有一個夢想,就是希望把所有的組件模塊組合即可組裝成一個完整的項目系統(或者至少可以大部分完成)。在之前介紹的《Winform開發框架之通用附件管理模塊》里面介紹了我的Winform開發框架的版圖,里面包含了我對Winform模塊化的一系列規划的組件,組件盡可能是適用於大多數的業務環境組合,以達到最大程度的重用和高效開發。
Winform開發框架是我集多年開發經驗以及積累而成,很多細節之處潤物細無聲,但卻是精粹心得所至,很多地方都希望是精益求精,力求把框架中的模塊當成一把把神兵利器,用到的時候,馬上就可以派生用場解決問題,這樣可以避免給客戶開發業務的時候,延誤戰機,或者因為事無巨細,都要從頭來過,效率大打折扣,而且時間和金錢的大投入也未見得取得好的效果。
上兩篇介紹了WInform框架中的通用定時服務管理模塊,《Winform開發框架之通用定時服務管理》、《Winform開發框架之通用定時服務管理2---如何開發定時服務應用》,主要介紹主要在常規數據同步的時候,如何快速利用定時服務管理的通用模塊,加上插件化的一些同步業務實現模塊,實現強大、高效、松耦合的定時服務管理。本篇繼續介紹Winform開發框架中的版圖部分,通用短信郵件通知模塊。
開發這個模塊的初衷是我在開發過的很多項目中,發現或多或少,都有短信通知、郵件通知、站內通知信息的需求,短信和郵件用的很多,也是大多數業務系統重復建設的模塊之一,如單位辦理業務要通知申請人,公司和客戶溝通交流,公司內部員工溝通,這些可能是通過短信、郵件或者站內信息(或叫系統內部的通知信息)。如果這些模塊能夠快速搭建的話,對項目組來說,節省的時間,提高的是效率。對單位企業來說,這是高質量代碼的保證,重復利用更可也減少重復的人力投資和成本支出。
1、模塊設計
首先我們知道,短信、郵件、站內信息這幾個業務的發送信息的時候,我們都希望記錄相關的發送例子,其中短信實現發送的機制比較多,可能通過自己企業內部的短信MAS代理機來發送,也可能是通過購買的外部的WebService服務發送,因此通過插件模塊的機制,實現短信發送邏輯的動態加載;郵件發送則利用.NET的郵件發送API,加上企業或者個人郵件發送參數即可實現,也是通過插件方式實現發送邏輯的動態加載;站內信息主要就是數據庫記錄,然后定時檢測是否有記錄即可,相對比較簡單。
短信、郵件、站內信息的數據庫設計,如下圖所示,他們三者之間共用一個模板表,通過不同的TemplateType來識別不同的信息模板,這樣信息模板表可以為短信、郵件、站內信息做更好的引用。
這里我們可以看到,我主要就是設計幾個表來存儲他們的發送記錄,對於具體的短信發送,郵件發送,我們采用插件方式實現具體發送邏輯的封裝,如下所示。
其中郵件發送接口和短信發送接口定義如下,方便實現基於插件方式的發送邏輯模塊。
public interface IMailSend { /// <summary> /// 發送外部郵件(自定義郵件配置,如個人郵件) /// </summary> /// <param name="mailInfo">發送郵件信息</param> /// <param name="settingInfo">SMTP協議設置信息</param> /// <returns></returns> CommonResult Send(MailInfo mailInfo, SmtpSettingInfo settingInfo); /// <summary> /// 發送外部郵件(系統配置,系統郵件) /// </summary> /// <param name="mailInfo">發送郵件信息</param> /// <returns></returns> CommonResult Send(MailInfo mailInfo); } public interface ISmsSend { /// <summary> /// 發送短信 /// </summary> /// <param name="content">短信內容</param> /// <param name="mobiles">手機號碼(多個號碼用”,”分隔)</param> /// <param name="sendTime">預約發送時間</param> /// <returns></returns> CommonResult Send(string content, string mobiles, DateTime? sendTime); }
2、軟件使用界面
1)短信界面功能
具體的模塊界面如下,輸入信息發送后成功的界面如下所示。
發送信息后,手機收到的結果如下所示。
短信還可以使用帶有通訊錄的發送界面,以及模板功能等方便性功能操作,如下所示。
通訊錄可以通過調用窗體函數進行數據綁定,這樣在調用的時候,只需要按照要求填寫相應的數據就可以顯示個人專屬的通訊錄了,方便勾選手機進行發送短信,操作綁定代碼如下所示。
private void btnSendWithList_Click(object sender, EventArgs e) { FrmSendSMSWithList dlg = new FrmSendSMSWithList(); Dictionary<string, List<ContactInfo>> dict = new Dictionary<string,List<ContactInfo>>(); List<ContactInfo> list = new List<ContactInfo>(); string category = "個人通訊錄"; list.Add(new ContactInfo(category, "001", "伍華聰", "18620292076", "wuhuacong@163.com")); list.Add(new ContactInfo(category, "002", "張三", "18620292077")); list.Add(new ContactInfo(category, "003", "李四", "18620292078")); dict.Add(category, list); dlg.BindTreeData(dict); dlg.ShowDialog(); }
2)郵件發送界面
可以把郵件保存為模板,方便第二次引用,也可以從模板中選取已有的郵件內容進行發送,郵件模板界面如下所示。
郵件發送成功后,會在郵件發送歷史中留下發送的內容記錄,如下界面所示。
郵件發送成功的同時,我們可以看到騰訊的QQ郵件提示信息,如下所示。
進一步查看郵件的信息,可以看到郵件里面的內容如下所示,由於采用了RichEditControl控件編輯數據,因此嵌入到編輯器里面的圖片(本地插入或者動態截圖),都可以進行正常發送,利用這個特點,可以編輯圖文並茂的郵件信息,而且RichEditControl控件支持直接從Word文檔中直接加載等功能,該控件的使用,我會另外開一篇隨筆進行介紹。
另外,和短信發送一樣,也可以通過動態綁定用戶的通訊錄,然后發送的時候,選定即可,如下所示。
3)站內信息使用界面
站內信息,可以用於系統內部用戶的信息交流,業務信息通知等用途,用戶登錄系統后,就可以看到系統內部用戶發給自己的通知信息。
這個功能沒有調用其他外部的插件模塊進行處理,直接就是把數據存儲到數據庫,然后對方定時獲取到通知后進行提示或者查看,界面如下所示。
3、通用短信郵件通知模塊控件的調用
通用短信郵件通知模塊已經對這幾類業務進行較好的封裝了,包括Winform界面部分的處理,也已經進行了較好的設計和封裝,因此和我的權限管理模塊、字典管理模塊一樣,非常方便使用的。
下面為了介紹具體三個模塊的使用,我使用了一個測試界面作為演示,如下所示。
各個按鈕的實現代碼如下所示,從中我們可以看到具體的模塊調用了。
/// <summary> /// 短信發送模塊調用 /// </summary> private void btnSendSMS_Click(object sender, EventArgs e) { FrmSendSMS dlg = new FrmSendSMS(); dlg.ShowDialog(); } /// <summary> /// 帶通訊錄的短信發送模塊調用 /// </summary> private void btnSendWithList_Click(object sender, EventArgs e) { FrmSendSMSWithList dlg = new FrmSendSMSWithList(); Dictionary<string, List<ContactInfo>> dict = new Dictionary<string,List<ContactInfo>>(); List<ContactInfo> list = new List<ContactInfo>(); string category = "個人通訊錄"; list.Add(new ContactInfo(category, "001", "伍華聰", "18620292076", "wuhuacong@163.com")); list.Add(new ContactInfo(category, "002", "張三", "18620292077")); list.Add(new ContactInfo(category, "003", "李四", "18620292078")); dict.Add(category, list); dlg.BindTreeData(dict); dlg.ShowDialog(); } /// <summary> /// 短信發送歷史 /// </summary> private void btnSMSHistory_Click(object sender, EventArgs e) { FrmSMSHistory dlg = new FrmSMSHistory(); dlg.ShowDialog(); } /// <summary> /// 郵件發送模塊調用 /// </summary> private void btnSendMail_Click(object sender, EventArgs e) { FrmSendMail dlg = new FrmSendMail(); dlg.Owner = this;//記錄用來隱藏 dlg.Show(); } /// <summary> /// 帶通訊錄的郵件發送模塊調用 /// </summary> private void btnSendEmailWithList_Click(object sender, EventArgs e) { FrmSendMailWithList dlg = new FrmSendMailWithList(); Dictionary<string, List<ContactInfo>> dict = new Dictionary<string, List<ContactInfo>>(); List<ContactInfo> list = new List<ContactInfo>(); string category = "個人通訊錄"; list.Add(new ContactInfo(category, "001", "伍華聰", "18620292076", "wuhuacong@163.com")); list.Add(new ContactInfo(category, "002", "張三", "18620292077", "wuhuacong@hotmail.com")); list.Add(new ContactInfo(category, "003", "李四", "18620292078", "6966254@qq.com")); dict.Add(category, list); dlg.BindTreeData(dict); dlg.ShowDialog(); } /// <summary> /// 郵件發送歷史 /// </summary> private void btnMailHistory_Click(object sender, EventArgs e) { FrmMailHistory dlg = new FrmMailHistory(); dlg.ShowDialog(); } /// <summary> /// 站內信息發送模塊調用 /// </summary> private void btnSendBroad_Click(object sender, EventArgs e) { FrmSendBroad dlg = new FrmSendBroad(); dlg.ShowDialog(); } /// <summary> /// 站內信息發送歷史 /// </summary> private void btnBroadHistory_Click(object sender, EventArgs e) { FrmBroadHistory dlg = new FrmBroadHistory(); dlg.ShowDialog(); }
4、短信郵件插件化開發及設置
我們從上圖可以看到,里面對於郵件和短信,都定義了接口,用於具體模塊的實現,自己可以實現這些接口,然后配置好exe.config里面的參數,就可以被調用了。
下面是我為短信和郵件接口開發了幾個實現類,其中MyMailSend是發送郵件的實現類,其他幾個是基於各種MAS短信接口和WebService接口的短信發送實現。
開發好后,在配置項里面設置一下插件的相關參數即可,如下所示的內容。