關說不練假把式,在上一,二篇中介紹了我心目中的CRUD的樣子 基於之前的理念,我開發了一個命名為PasteTemplate的項目,這個項目呢後續會轉化成項目模板,轉化成項目模板後,後續需要開發新的項目就可以基於這個模板創建,這樣就不要copy一個舊的項目,然後刪刪刪,改改改,重命名等操作了 強迫症, ...
關說不練假把式,在上一,二篇中介紹了我心目中的CRUD的樣子
基於之前的理念,我開發了一個命名為PasteTemplate的項目,這個項目呢後續會轉化成項目模板,轉化成項目模板後,後續需要開發新的項目就可以基於這個模板創建,這樣就不要copy一個舊的項目,然後刪刪刪,改改改,重命名等操作了
強迫症,一個項目的名字就得統一,心裡才舒服
那麼本次作者就帶來了實物,本次主要介紹管理端的內容,我們一起來看看
這個是後臺,目前使用的是HTML原生寫的,如果說使用VUE的話,會更簡單,這個後續看情況推出!
先用原生的原因呢,一是順手,二是前期是規劃期,改動比較多,這個項目開發過程我是錄製了視頻的,後續會和項目模板一併放出來!
這個管理端有多少代碼?
可能說代碼量不太合適,我就列出下各個文件的大概情況(文件採用鬆散編輯模式,就是一個花括弧就一行的寫法,所以不存在刻意壓縮代碼行的問題哈!)
文件 | 大小 | 行數 | 說明 |
---|---|---|---|
login/index.html | 8KB | 177 | 登陸頁面,賬號密碼驗證碼登陸 |
login.less | 9KB | 381 | 登陸頁面的樣式文件 |
pasteform/index.html | 12KB | 212 | 表格列表頁面的主UI頁面 |
pasteform/index.js | 22KB | 682 | 表格頁面的主邏輯JS頁面 |
pasteform/index.less | 14KB | 656 | 表格頁面的樣式文件 |
pasteform/view.html | 12KB | 184 | 表單新增編輯頁面的UI文件 |
pasteform/view.js | 27KB | 820 | 表單新增編輯頁面的邏輯JS代碼 |
pasteform/view.less | 10KB | 499 | 表單編輯新增頁的樣式文件 |
index.html | 11KB | 225 | 首頁,也就是菜單頁面,上圖的這個主頁面,菜單採用API獲取的動態方式 |
index.less | 5KB | 311 | 首頁的樣式文件 |
lib/api.js | 18KB | 598 | ajax請求,一些基礎函數的轉化等,相當於幫助類 |
還有一些其他的三方組件,比如jquery.js,layer.js,daterange.js,pagenum.js,datepicker.js,template.js,wangedit.js等
為啥才這麼幾個文件?
看上圖至少有4個表為啥才這麼幾個文件?
文件復用了
比如許可權的列表頁面為pasteform/index.html?path=roleInfo,而用戶的列表頁面為pasteform/index.html?path=userInfo
對應的表單頁面為pasteform/view.html?path=roleInfo和pasteform/view.html?path=userInfo
實現原理
在執行UI之前,獲取對應的模型的模型內容,比如新增的時候,獲取對應的AddDto模型的模型屬性,包括不限於,包含了哪些屬性(是否禁用add,edit,del等),有哪些欄位,欄位的特性是哪些,還有就是欄位的預設值!
同理在編輯的時候,會把要編輯的主鍵帶入API中,先查詢這個UpdateDto的模型數據,然後基於ID獲取這個模型的值,組合後返回給前端
至於表格,請求的時候要讀取ListDto和對應的搜索InputQueryDto的內容!
表格頁面功能介紹
從上圖中可以看到大概幾個要點!
1.左側的菜單是採用動態模式的,看圖的中間部分的菜單類型可以看到和左側的一一對應!
2.右側區域的功能都是動態的,貌似除了關鍵字輸入和搜索按鈕是固定的,其他都是動態控制的
3.搜索區域的內容和類型由後端的InputQueryXXX的模型來控制
4.新增,編輯和刪除按鈕由對應模型的ListDto控制
5.列表中支持排序,比如上圖的ID,排序,層級等
6.列表中支持直接顯示外表的對應欄位,比如父級ID那一列,直接顯示了父級ID對應的許可權的名稱
7.支持狀態快編,也就如上圖的switch,這個是可以交互的!
外表輸入
支持外表輸入,比如要查詢某一個角色有多少用戶,那麼用戶列表中,角色ID作為篩選,那角色ID不能自己手動輸入吧
點擊後,會彈出角色列表頁面,選擇要查詢的,然後點擊確定,就會把對應的值輸入到輸入框中(顯示的是友好名)
在Model中是這樣配置外表選擇的
時間區間
有些時候需要查詢時間區間,比如本月新增的用戶有多少
在Model中,時間區間其實是由2個欄位表示的,開始欄位和結束欄位,當然了結束欄位需要配置隱藏,如下圖
單選
有時候查詢需要選擇某一個狀態,比如查詢禁用的用戶有多少,查詢狀態正常的用戶有多少(也就是一個select的選項)
在Model中體現為:
表單頁面功能介紹
表單頁面也就是新增數據,或者編輯,如下
基本輸入
一些比如文本,文本域,數字,開關等的輸入,和基本的一致,約定輸入框的名稱為Model對應欄位的註釋部分的前部分,後部分則為placeholder,前後部分使用空格隔開!
頭像圖片
不單單支持單圖,還支持多圖模式!
富文本模式
系統採用的是wangEdit v5的版本
時間模式
時間上支持單時間和時間區間模式
單選模式
單選有一個問題,就是選項是固定的,也就是要預先寫好,如果是動態的,則使用外表的模式
外表單選
點擊和表格那邊的操作模式是一樣的
要實現這些功能,只需要在對應的Model做屬性的標記即可,如下
///<summary>
///測試表 用於測試CURD的表
///</summary>
public class TestTableAddDto
{
///<summary>
///姓名 模擬短文本輸入
///</summary>
[MaxLength(32)]
[Required]
public string Name { get; set; }
///<summary>
///頭像 模擬圖片上傳
///</summary>
[MaxLength(128)]
[ColumnDataType("image","1","head","60*60")]
public string Head { get; set; }
///<summary>
///年齡 模擬輸入number
///</summary>
[Range(5, 90, ErrorMessage = "年齡必須限定在5~90之間!")]
public int Age { get; set; }
///<summary>
///文本區域 模擬文本區域的輸入
///</summary>
[MaxLength(128)]
public string Desc { get; set; }
///<summary>
///富文本 模擬富文本,前端HTML的是使用wangEditv5
///</summary>
public string Blog { get; set; }
///<summary>
///加入日期 模擬必填時間的輸入
///</summary>
public DateTime JoinDate { get; set; }
///<summary>
///單選 一般表示狀態,內定的,有點像Enum,關於Enum後續會支持
///</summary>
[ColumnDataType("select", "[{\"name\":\"日類型\",\"value\":0},{\"name\":\"月類型\",\"value\":1},{\"name\":\"年類型\",\"value\":2}]")]
public int DateType { get; set; }
///<summary>
///角色ID 這裡一般用於外表,就是選擇其他表的一個數據作為輸入內容
///</summary>
[ColumnDataType("outer", "gradeInfo", "", "id", "name")]
public int GradeId { get; set; }
///<summary>
///成績 模擬前端限定2位小數
///</summary>
public double Score { get; set; }
/// <summary>
/// 會員周期 會員生效區間
/// </summary>
[ColumnDataType("daterange","dateStart","dateEnd")]
public DateTime DateStart { get; set; }
/// <summary>
/// 會員周期 會員生效區間
/// </summary>
[ColumnDataType("hidden")]
public DateTime DateEnd { get; set; }
}
至於編輯模式,其實編輯模式和新增模式的欄位屬性標記同樣適用!
在編輯模式中有一個特別的,就是外表顯示,比如上面的外表選擇中的選擇父級,則在編輯中是這樣的
補充
對於上面其實比較糾結的地方應該就是欄位的特性ColumnDataType
image
相對於後面的 head 來說,這裡是大圖模式,在ListDto中表示使用圖片的模式渲染
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 數字 | 1 | 圖片數量 |
args2 | 字元 | cate | 存放在什麼位置,上傳圖片的時候會附帶到參數type中 |
args3 | 字元 | 60*60 | 圖片是否需要壓縮,壓縮的寬高,不壓縮的設置為0,比如60*0 |
args4 | 字元 | arr或str | 預設值str對應欄位的類型,是array類型還是string類型,如果是string類型多個之間用,隔開 |
head
使用方式同 image 這裡表示的是小圖標模式
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 數字 | 1 | 圖片數量 |
args2 | 字元 | cate | 存放在什麼位置,上傳圖片的時候會附帶到參數type中 |
args3 | 字元 | 60*60 | 圖片是否需要壓縮,壓縮的寬高,不壓縮的設置為0,比如60*0 |
args4 | 字元 | arr或str | 預設值str對應欄位的類型,是array類型還是string類型,如果是string類型多個之間用,隔開 |
region
小程式中的地區選擇,可以配置精確度,到區還是到縣
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 字元 | region | 表示地址選擇的層級,可選region和sub-district |
args2 | 字元 | str | 可用值str或者arr 表示返回的數據類型,str的時候用,隔開 |
outer
表示一個值需要從外表獲取,編輯的時候如何顯示? 比如fatherId,extendRole
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 字元 | cateInfo | 外表的名稱,對應模板的path,或者路徑,路徑一定附帶了/字元示例./abc.html |
args2 | 字元 | extendCates | 表示顯示的數據,需要和下麵2個配合,是一個當前的擴展,目標數組要配置hidden |
args3 | 字元 | id | 獲取返回對象的屬性,一般為id |
args4 | 字元 | name | id的友好名稱顯示,這裡指的是外表,比如cateId,需要打開catelist頁面,選擇後,返回cate,則name作為友好顯示,id作為實際值 |
outers
outer的複數版本,表示可以從外部列表中選擇多個,比如在創建賬號的時候給他綁定多個角色,就用這個!
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 字元 | cateInfo | 外表的名稱,對應模板的path,或者路徑,路徑一定附帶了/字元示例./abc.html |
args2 | 字元 | extendCates | 表示顯示的數據,需要和下麵2個配合,是一個數組,目標數組要配置hidden |
args3 | 字元 | id | 獲取返回對象的屬性,一般為id |
args4 | 字元 | name | id的友好名稱顯示,這裡指的是外表,比如cateId,需要打開catelist頁面,選擇後,返回cate,則name作為友好顯示,id作為實際值 |
outerdisplay
ListDto中用於外表的顯示,比如有欄位cateInfoId,對應的ExtendCateInfo要標記為outerdisplay,args2配置為extendCateInfo?.name || '',否則會顯示為[object object]
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 字元 | cateInfoId | 表示這個欄位的值,一般不顯示 |
args2 | 字元 | extendCateInfo?.name || '' | 表示顯示的名稱,友好名稱,需要後端支持,在前端會處理成.display |
navigator
表示這個值需要使用頁面從另外一個列表中獲取,這裡表示小程式端的,建議使用outer outerdisplay
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 字元 | cate.name || '' | 表示顯示cate.name或者空這個一般用於ListDto中 |
args2 | 字元 | cateInfo | 外表的名稱,對應模板的path,可以為空 |
args3 | 字元 | /pages/cate/index/?model=select | 如果對應的表不用模板,則直接表示路徑 |
datetime
預設的yyyy-MM-dd HH:mm:ss的格式
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 字元 | yyyy-MM-dd HH:mm:ss | 表示時間使用的格式 |
hidden
表示隱藏這個欄位,一般是主鍵ID,或者外錶鏈接過來的會這配置,比如需要給cate添加子項,則添加由cate那邊過來
這個也適用於ListDto
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 字元 | bind | 如果不填表示隱藏,如果填寫了表示頁面的query中model=xxx的時候不隱藏,表示非xxx的時候隱藏,xxx的時候不隱藏 |
password
密碼框模式
query
需要和 hidden 配合使用一般,表示在表單的時候使用哪個參數作為數據
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 字元 | cateid | 表示使用url中的哪個參數讀取值 |
readyonly
表示這個欄位是只讀的,一般是編輯的時候生效
richtext
如果是字元串,沒有設置maxlength,預設就會變更成richtext,也可以手動強制配置
textarea
如果是字元串,設置maxlength,且設置的值大於128,預設就會變更成textarea,也可以手動強制配置
select
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 字元 | [{"name":"大","value":"1"},{"name":"小","value":"2"}] | 表示單選的可選值,name是顯示 value是值 |
args2 | 字元 | 表示值得類型,這裡是單個,跟隨主類型走 |
selects
表示多選,這個表示的是頁面上的多選
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 字元 | [{"name":"大","value":"1"},{"name":"小","value":"2"}] | 表示單選的可選值,name是顯示 value是值 |
args2 | 字元 | str | 表示值得類型是一個數組,還是字元串,如果是字元串則使用逗號隔開 |
sort
表示排序,表示欄位的順序,一般表格比較會使用這個
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 數字 | 0 | 小的排在前面,預設為0 |
link
這個用於表格顯示,一般表示用於顯示外表的數據,這個將棄用,使用outerdisplay替換
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 字元 | extendCate.name | 顯示的外錶鏈接,示例extendCate?.name || ''表示顯示cate.name或者空這個一般用於ListDto中 |
width
表示這個欄位在表格得寬度,可以為*或者對應得數字,是表格得列的寬度的權重,這個適用於ListDto
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 字元 | 60 | 表示這個列的寬度,可以為數字也可以是*比如3*這樣 |
orderby
表示基於哪個欄位進行排序,這個一般是ListDto表示表格中,可以基於哪個欄位進行排序查詢
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 字元 | id | 表示使用id正序排序 |
args2 | 字元 | id desc | 表示使用倒敘排序 |
datalist
前端表示使用datalist作為選擇數據源,前端需要把datalist的id賦值給datalistid,預設為欄位name,這個規則適用於表單和QueryDto
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 字元 | [{"name":"正常","value":"1","selected":true}] | JSON的字元串,也可以為空 |
args2 | 字元 | data_pro | 表示調用哪個datalist數據,表示datalist的id,和args1互斥 |
args3 | 字元 | read_pro_datalist() | 表示需要使用eval執行哪個函數,一般和args2配合使用,和args1互斥 |
daterange
主欄位需要設置為daterange,其他欄位需要設置hidden,在最後組合數據的時候,會基於參數生成對應的,應該要設置為可null格式
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 字元 | sdate | 表示開始時間,最後會傳送yyyy-MM-dd 00:00:00的格式數據 |
args2 | 字元 | edate | 表示結束時間,如果你選擇2024-08-31,最後上送的會是2024-08-31 00:00:00 |
args3 | 字元 | yyyy-MM-dd 00:00:00 | 表示時間的格式化,預設使用yyyy-MM-dd 00:00:00 |
disable
特殊限定,限定於class的,表示禁用這個模型的哪些功能,這個一般用於ListDto,因為這些功能都在列表頁面
欄位 | 類型 | 示例 | 說明 |
---|---|---|---|
args1 | 字元 | add | 表示忽略新增,也就是不顯示新增按鈕 |
args2 | 字元 | edit | 表示忽略編輯,表示列表中沒有編輯的這個選項,有些數據只能看,不需要新增和編輯 |
args3 | 字元 | del | 表示這個表沒有刪除,頁面UI中不需要刪除按鈕 |
目前還在思考有哪些常用的需要添加進來,
目前還是缺少很多東西的
1.index.js和view.js有很多重覆的函數,可以考慮把他們2個綜合一下,後續好維護
2.一些特殊的常用的功能的實現,比如作者的PasteSpider中大量的使用了datalist
3.如何在小程式上接入,畢竟這個項目的初衷就是為瞭解決小程式上大量表單輸入和編輯的問題而提出的方案
4.後續大家如何使用,如何按照自己的需求修改規則等
案例項目和項目模板視頻如下
https://player.bilibili.com/player.html?aid=113093837524694
項目源碼
項目源碼已放置Gitee,點擊訪問
我們下期見