X-Admin&ABP框架開發-資料字典

微笑刺客D發表於2019-07-07

  在業務型的系統開發中,我們需要維護各種個樣的型別,比如客戶型別、客戶行業、商品型別等等,這些型別往往資訊量不多,並且相似度極高,如果採用一型別一表去設計,將會造成極大的工作量,通過將這部分型別的資訊進行抽象,利用欄位去儲存型別區分,共用表結構,來達到相容各種型別的功能,也就是設計一個資料字典,而對於一個具體型別來講,是有多個選項的,比如性別,有男女,行業有工農商等,對於這部分選項,可抽象為某個型別下的字典項,即資料字典項。

 

一、資料字典設計思路

  1、從客戶型別、商品型別、行業型別來抽象考慮,首先三者都存在一個型別描述,即客戶、商品、行業,同時,三者是本質是不同的,並且,隨著業務上的需求越來越多,更多的xx型別將會加入,因此,單從型別考慮出發,就存在三個點了,如型別名稱、型別獨立、數量擴充套件,因此在考慮表結構設計時,就可以先考慮到這三點了,同時還有一個關鍵的資訊,便是,在系統設計過程中,這些型別其實便已經確定完畢了,而不是說,在開發完畢,再去系統中增加型別。

   

   2、從具體的某個型別出發考慮,比如以商品型別為例,存在日用品、電子產品、化妝品等,同樣是存在幾個關鍵資訊,比如型別項名稱、型別項獨立、型別項數量擴充套件,型別項的歸屬,而這部分資訊,往往是由客戶去維護的,屬於系統開發完畢後期的資訊維護,在此,不考慮型別項的先後順序問題,如有需要可以擴充套件。

   

  按照這些資訊點,可以對資料字典設計一些必要的欄位,如型別名稱即TypeName、 型別獨立便是型別間相互獨立,但是這裡也存在一個型別間的上下父子問題,暫不加入進來,該父子問題使用場景較少,但又存在,如果按照“二八原則”的話,我還是喜歡把“八”的部分完成。對於資料字典項而言,按照給定的必要資訊,設計成如下結構,其中的業務程式碼,是需要唯一的,比如對於性別來將,業務程式碼便是1或0,來代表男女,這部分可由客戶的系統管理員進行維護。

  

 

二、完成資料字典設計

   在明確了這些基礎資訊後,開始在專案中完成設計過程,首先得明確資料字典本身的歸屬,資料字典是為整個業務而服務的,因此我把它劃分到核心層這一級別中,首先在領域層設定Core層資料夾,用來存放為整個業務提供基礎設施的功能模組。

   

  1、在Core層中加入資料字典模組,結構設計如:

  

  開始建立資料字典類,並新增設計的欄位,以保證夠用為前提,或許更多場景下會出現諸如父子字典情形,或是對字典內容的描述等,暫不考慮。

/// <summary>
/// 核心_資料字典
/// </summary>
[Table("Core_DataDictionary")]
public class DataDictionary : Entity<long>
{
    public const int MaxNameLength = 30;

    /// <summary>
    /// 字典型別
    /// </summary>
    [StringLength(MaxNameLength)]
    public string TypeName { get; set; }

    /// <summary>
    /// 關聯資料字典項
    /// </summary>
    public virtual ICollection<DataDictionaryItem> DataDictionaryItem { get; set; }
}

   在增加資料字典項類,並新增設計時的欄位資訊,這裡我通過資料註解完成對欄位的一些約束,如長度約束,表名的對映等。

/// <summary>
/// 核心_資料字典項
/// </summary>
[Table("Core_DataDictionaryItem")]
public class DataDictionaryItem : Entity<long>
{
    public const int MaxCodeLength = 5;
    public const int MaxNameLength = 30;

    /// <summary>
    /// 業務程式碼
    /// </summary>
    [StringLength(MaxCodeLength)]
    public string Code { get; set; }

    /// <summary>
    /// 型別項名稱
    /// </summary>
    [StringLength(MaxNameLength)]
    public string Name { get; set; }

    /// <summary>
    /// 資料字典Id
    /// </summary>
    public long DataDictionaryId { get; set; }

    /// <summary>
    /// 關聯資料字典項
    /// </summary>
    public virtual DataDictionary DataDictionary { get; set; }
}

  加入到DbContext中,新增一個遷移並更新資料庫。

  

  2、開始完成應用層的封裝工作,在應用層定義了幾個常用的對字典的一些操作,諸如新增刪除修改等常見操作,此處的資料字典暫時通過手動加入,而不是將已有資料字典或是更改了的資料字典自動更新到資料庫中。

/// <summary>
/// 獲取資料字典集合
/// </summary>
/// <returns></returns>
Task<ListResultDto<DataDictionaryListDto>> GetAllDataDictionaryListAsync();

/// <summary>
/// 獲取資料字典記錄
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<DataDictionaryEditDto> GetDataDictionaryForEditAsync(NullableIdDto<long> input);

/// <summary>
/// 新增或更新資料字典記錄
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task CreateOrUpdateDataDictionaryAsync(CreateOrUpdateDataDictionaryInput input);

/// <summary>
/// 刪除資料字典記錄
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
Task DeleteDataDictionaryAsync(List<EntityDto<long>> inputs);

/// <summary>
/// 根據字典型別名稱獲取資料字典集合
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<ListResultDto<DataDictionaryListDto>> GetDataDictionaryListByTypeNamesAsync(GetDataDictionaryListByTypeNamesInput input);

   對資料字典項也準備了幾個方法,用於對某一具體資料字典型別增加刪除修改資料字典項。

/// <summary>
/// 獲取資料字典項
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<DataDictionaryItemEditDto> GetDataDictionaryItemForEditAsync(NullableIdDto<long> input);

/// <summary>
/// 新增或更新資料字典項
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task CreateOrUpdateDataDictionaryItemAsync(CreateOrUpdateDataDictionaryItemInput input);

/// <summary>
/// 刪除資料字典項
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
Task DeleteDataDictionaryItemAsync(List<EntityDto<long>> inputs);

/// <summary>
/// 根據字典型別和字典項名稱獲取字典項值
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<GetDataDictionaryItemNameOutput> GetDataDictionaryItemNameAsync(GetDataDictionaryItemNameInput input);

/// <summary>
/// 獲取資料字典列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<ListResultDto<DataDictionaryItemListDto>> GetDataDictionaryItemListAsync(GetDataDictionaryItemListInput input);

   在應用層建立一個全域性常量資料字典類,用於儲存資料字典資訊,該部分資訊也將成為需要維護到系統中的必備資訊,並且,在系統中如有地方需要呼叫到資料字典型別時,不需要寫死程式碼。

/// <summary>
/// 資料字典型別儲存表
/// </summary>
public class DataDictionaryTypeConsts
{
    #region 分瓶規則
    public const string GroupRule_FixAtive = "固定劑及使用";

    public const string GroupRule_ContainerType = "容器型別";
    #endregion
}

   3、完成控制器層呼叫及頁面中對資料字典的管理 ,對於字典資訊而言,足夠在介面中一覽全貌,因此頁面設計時,直接以樹形結構加表格展示即可,左側資料型別樹形結構,右側相應的資料型別項表格。

<div class="layui-row">
    <div class="layui-col-md2 layui-col-xs12">
        <ul id="tree" class="ztree" style="padding: 0px; border: 1px solid #ddd; overflow: auto;"></ul>
    </div>
    <div class="layui-col-md10 layui-col-xs12">
        <table class="layui-table"
                lay-data="{height: 'full-180', page:true, id:'mainList'}"
                lay-filter="list" lay-size="xs">
            <thead>
                <tr>
                    <th lay-data="{checkbox:true, fixed: true}"></th>
                    <th lay-data="{field:'code', sort: true}">業務程式碼</th>
                    <th lay-data="{field:'name'}">名稱</th>
                    @if (await PermissionChecker.IsGrantedAsync(PermissionNames.Pages_Core_DataDictionaryItem_Edit) ||
                await PermissionChecker.IsGrantedAsync(PermissionNames.Pages_Core_DataDictionaryItem_Delete))
                    {
                        <th lay-data="{fixed:'right', align:'center', toolbar: '#barList'}"></th>
                    }
                </tr>
            </thead>
        </table>
    </div>
</div>

 

三、資料字典頁面展示

  利用layui節省了不少時間,對於前端東西不太精通,只能夠用,勉強實現了資料字典的一些操作,其中的資料字典型別是按照開發過程中可能用到的進行加入的,合理的存在,而不是空穴來風,在之前的DataDictionaryConst類中可以定義需要用到的資料字典型別,此處並沒有直接從那裡增加後自動匯入到資料庫中。 

 

 至此,資料字典的初步邏輯設計完畢,至於要加入更為豐富的功能,諸如排序,父子資料型別,或是資料型別描述,均可擴充套件。 

 程式碼地址:https://gitee.com/530521314/Partner.Surround.git

 

2019-07-07,望技術有成後能回來看見自己的腳步

相關文章