在我這個(gè)系列中恢氯,我主要以我正在開發(fā)的云會(huì)員管理系統(tǒng)為例進(jìn)行介紹Web API的應(yīng)用舶沿,由于云會(huì)員的數(shù)據(jù)設(shè)計(jì)是支持多個(gè)商家公司嘶朱,而每個(gè)公司又可以包含多個(gè)店鋪的特愿,因此一些字典型的數(shù)據(jù)需要考慮這方面的不同仲墨。如對(duì)于證件類型,收費(fèi)處理狀態(tài)揍障,民族目养,職稱等這些固定化的內(nèi)容,我們可以放到全局字典里面毒嫡,但是對(duì)于一些如會(huì)員相關(guān)的字典數(shù)據(jù)癌蚁,如產(chǎn)品單位、產(chǎn)品類型等內(nèi)容兜畸,如果也全部規(guī)定為全局的系統(tǒng)字典努释,那么就缺乏靈活性,這些數(shù)據(jù)應(yīng)該可以由各自進(jìn)行差異化處理咬摇。
1伐蒂、云會(huì)員系統(tǒng)的字典數(shù)據(jù)模型
我們先來了解下基于Web API接口的云會(huì)員管理系統(tǒng)的總體界面效果。
由于一般的云會(huì)員系統(tǒng)菲嘴,都是允許用戶注冊(cè)一個(gè)公司饿自,然后公司層面開設(shè)多個(gè)商鋪的汰翠,如系統(tǒng)的登陸界面如下所示龄坪。
因此數(shù)據(jù)的范圍需要考慮的更廣,他們的關(guān)系如下所示复唤。
而我們?cè)仍O(shè)計(jì)的字典模型如下所示健田。
而在公司數(shù)據(jù)這個(gè)層次上,我們需要考慮公司層級(jí)的數(shù)據(jù)字典存儲(chǔ)佛纫,但是我們進(jìn)一步分析可以看到妓局,雖然數(shù)據(jù)字典數(shù)據(jù)是公司層級(jí)的,但是數(shù)據(jù)字典的類型(如證件類型呈宇、產(chǎn)品類型等)這些是固定不變的好爬,也就是我們?nèi)绻鎯?chǔ)公司層級(jí)的字典數(shù)據(jù),那么也只是需要存儲(chǔ)對(duì)應(yīng)的字典項(xiàng)目即可甥啄。因此我們可以增加多一個(gè)和TB_DictData的數(shù)據(jù)表類似的表進(jìn)行存儲(chǔ)即可存炮,它的數(shù)據(jù)設(shè)計(jì)如下所示。
為了方便在系統(tǒng)里面使用同一的字典項(xiàng)目?jī)?nèi)容,我們創(chuàng)建一了一個(gè)統(tǒng)一的字典項(xiàng)目管理模塊穆桂,也就是系統(tǒng)字典管理界面宫盔,如下所示。
2享完、公司層級(jí)的字典數(shù)據(jù)存儲(chǔ)實(shí)現(xiàn)
有了上面的設(shè)計(jì)模型灼芭,相信大多數(shù)人員都可以想到它的具體實(shí)現(xiàn)思路了。
首先我們需要以系統(tǒng)字典數(shù)據(jù)為參考般又,如默認(rèn)就是取系統(tǒng)的字典項(xiàng)目數(shù)據(jù)彼绷,如果公司級(jí)別的用戶修改或者刪除了字典數(shù)據(jù)內(nèi)容,那么對(duì)應(yīng)的字典類別的字典項(xiàng)目就應(yīng)該以修改的為準(zhǔn)了茴迁。
但是我們不可能為新建公司賬戶的時(shí)候苛预,都為每個(gè)公司自動(dòng)創(chuàng)建一份對(duì)應(yīng)類型的字典數(shù)據(jù),那樣稍顯麻煩笋熬,而且一開始就創(chuàng)建也比較麻煩热某。
先建立一個(gè)公司字典的數(shù)據(jù)管理界面,它和字典數(shù)據(jù)管理界面一樣胳螟,不過是存儲(chǔ)在另外一個(gè)表里面昔馋,自動(dòng)根據(jù)當(dāng)前用戶的公司標(biāo)識(shí)進(jìn)行存儲(chǔ)的。
批量添加公司字典的數(shù)據(jù)如下所示糖耸。
一般我們?cè)谑褂霉緦蛹?jí)的字典數(shù)據(jù)或者系統(tǒng)公共層級(jí)的字典數(shù)據(jù)的時(shí)候秘遏,都是根據(jù)字典類型進(jìn)行判斷的。
因此在公司層級(jí)根據(jù)字典項(xiàng)目類型獲取數(shù)據(jù)的時(shí)候嘉竟,我們?cè)跇I(yè)務(wù)接口底層做了判斷邦危,判斷如果對(duì)應(yīng)公司的字典項(xiàng)沒有數(shù)據(jù),則復(fù)制一份過去舍扰,如果公司層次有對(duì)應(yīng)的數(shù)據(jù)類型倦蚪,那么就獲取公司層級(jí)的字典項(xiàng)目數(shù)據(jù)即可。
具體的代碼邏輯如下所示边苹。
/// <summary>
/// 根據(jù)字典類型名稱獲取所有該類型的字典列表集合
/// </summary>
/// <param name="dictType">字典類型名稱</param>
/// <param name="corpId">公司ID</param>
/// <returns></returns>
public List<CorpDictDataInfo> FindByDictType(string dictTypeName, string corpId)
{
ICorpDictData dal = baseDal as ICorpDictData;
List<CorpDictDataInfo> list = dal.FindByDictType(dictTypeName, corpId);
//如果公司字典沒有數(shù)據(jù)陵且,則從系統(tǒng)字典獲取
if (list.Count == 0)
{
List<DictDataInfo> dict = BLLFactory<DictData>.Instance.FindByDictType(dictTypeName);
foreach (DictDataInfo info in dict)
{
list.Add(new CorpDictDataInfo(info, corpId));
}
//寫入公司字典表,避免下次再去獲取
foreach (CorpDictDataInfo info in list)
{
baseDal.Insert(info);
}
}
return list;
}
在Web API的控制器接口个束,還是和其他的處理一樣慕购,增加對(duì)應(yīng)的參數(shù)處理即可。
/// <summary>
/// 根據(jù)字典類型名稱獲取所有該類型的字典列表集合
/// </summary>
/// <param name="dictType">字典類型名稱</param>
/// <param name="corpId">公司ID</param>
/// <returns></returns>
[HttpGet]
public List<CorpDictDataInfo> FindByDictType(string dictTypeName, string corpId, string token)
{
//令牌檢查,不通過則拋出異常
CheckResult checkResult = CheckToken(token);
return BLLFactory<CorpDictData>.Instance.FindByDictType(dictTypeName, corpId);
}
在Facade層定義字典的對(duì)應(yīng)接口的時(shí)候茬底,我們的代碼如下所示
/// <summary>
/// 根據(jù)字典類型名稱獲取所有該類型的字典列表集合
/// </summary>
/// <param name="dictType">字典類型名稱</param>
/// <param name="corpId">公司ID</param>
/// <returns></returns>
[OperationContract]
List<CorpDictDataInfo> FindByDictType(string dictTypeName, string corpId);
在基于Web API的封裝調(diào)用接口沪悲,我們的調(diào)用封裝類如下所示。其中token以及Web API的相關(guān)參數(shù)處理阱表,在基類模塊進(jìn)行了封裝殿如,減少了很多代碼的拼接昌妹。
/// </summary>
/// <param name="dictType">字典類型名稱</param>
/// <param name="corpId">公司ID</param>
/// <returns></returns>
public List<CorpDictDataInfo> FindByDictType(string dictTypeName, string corpId)
{
var action = "FindByDictType";
string url = GetTokenUrl(action) + string.Format("&dictTypeName={0}&corpId={1}", dictTypeName, corpId);
List<CorpDictDataInfo> result = JsonHelper<List<CorpDictDataInfo>>.ConvertJson(url);
return result;
}
然后我們?cè)诮缑嫔系淖值漤?xiàng)目下拉列表,則可以通過擴(kuò)展函數(shù)的方式進(jìn)行綁定握截。
/// <summary>
/// 初始化字典列表內(nèi)容
/// </summary>
private void InitDictItem()
{
//初始化代碼
this.txtProductType.BindDictItemsByCorp("會(huì)員產(chǎn)品類型", LoginUserInfo.CompanyId);
}
/// <summary>
/// 綁定下拉列表控件為指定的數(shù)據(jù)字典列表[如果公司字典記錄不存在飞崖,則使用系統(tǒng)字典記錄,否則使用公司記錄]
/// </summary>
/// <param name="combo">下拉列表控件</param>
/// <param name="dictTypeName">數(shù)據(jù)字典類型名稱</param>
public static void BindDictItemsByCorp(this ComboBoxEdit combo, string dictTypeName, string corpId)
{
BindDictItemsByCorp(combo, dictTypeName, corpId, null);
}
/// <summary>
/// 綁定下拉列表控件為指定的數(shù)據(jù)字典列表[如果公司字典記錄不存在谨胞,則使用系統(tǒng)字典記錄固歪,否則使用公司記錄]
/// </summary>
/// <param name="combo">下拉列表控件</param>
/// <param name="dictTypeName">數(shù)據(jù)字典類型名稱</param>
/// <param name="defaultValue">控件默認(rèn)值</param>
public static void BindDictItemsByCorp(this ComboBoxEdit combo, string dictTypeName, string corpId, string defaultValue)
{
Dictionary<string, string> dict = CallerFactory<ICorpDictDataService>.Instance.GetDictByDictType(dictTypeName, corpId);
List<CListItem> itemList = new List<CListItem>();
foreach (string key in dict.Keys)
{
itemList.Add(new CListItem(key, dict[key]));
}
BindDictItems(combo, itemList, defaultValue);
}
以上就是一個(gè)整體性的思路,并在系統(tǒng)中能夠順利解決問題的做法胯努,希望大家可以借鑒牢裳。