bootstrap加载mysql数据库_bootstrap后台管理系统前后台实现(含数据库)
撰寫(xiě)本文檔目的是讓后續(xù)開(kāi)發(fā)者在理解該系統(tǒng)架構(gòu)的基礎(chǔ)上遵循一定規(guī)范保持系統(tǒng)架構(gòu)的合理性;同時(shí)也能夠達(dá)到允許沒(méi)有開(kāi)發(fā)經(jīng)驗(yàn)僅有web基礎(chǔ)的入門(mén)開(kāi)發(fā)者能夠通過(guò)復(fù)制粘貼的方式仿照demo示例進(jìn)行開(kāi)發(fā)的目的。
目? 錄
1? ? ? ?案例調(diào)研與選取... 2
1.1? ? ? 案例調(diào)研... 2
1.2? ? ? UI選取... 3
2? ? ? ?系統(tǒng)實(shí)現(xiàn)... 3
2.1? ? ? 實(shí)現(xiàn)效果... 3
2.2? ? ? 開(kāi)發(fā)規(guī)范... 6
3? ? ? ?詳細(xì)設(shè)計(jì)... 7
3.1? ? ? 框架介紹... 7
3.2? ? ? 數(shù)據(jù)庫(kù)設(shè)計(jì)... 8
3.3? ? ? 菜單管理... 8
3.4? ? ? 權(quán)限管理/角色管理... 11
3.5? ? ? 權(quán)限管理/權(quán)限分配... 13
3.6? ? ? 權(quán)限管理/用戶(hù)管理... 14
4? ? ? ?延伸思考... 14
5? ? ? ?致謝! 14
6? ? ? ?文檔說(shuō)明... 15
7? ? ? ?參考文獻(xiàn)... 15
案例調(diào)研與選取
案例調(diào)研
1)easyUI(No1)
圖片
2)easyUI(No2)
圖片
3)Bootstrap
圖片
4)vue/iview
圖片
以上四套UI框架對(duì)比分析,可以得出如下結(jié)論
結(jié)論:
easyUI功能完善,界面簡(jiǎn)潔友好,非常方便后端開(kāi)發(fā)人員開(kāi)發(fā),是優(yōu)秀的前端開(kāi)源框架,尤其適合后臺(tái)管理,但是非響應(yīng)式,頁(yè)面不會(huì)隨屏幕大小而變化,美觀(guān)方面(仁者見(jiàn)仁);
bootstrap是響應(yīng)式開(kāi)源框架,支持插件廣泛,界面相對(duì)酷炫,美觀(guān)方面(有目共睹),同樣也非常適合管理平臺(tái)的開(kāi)發(fā);
至于Vue和其它一些前端人員自己寫(xiě)的UI框架,必須要承認(rèn)Vue是不錯(cuò)的開(kāi)源框架,但是個(gè)人感覺(jué)對(duì)管理平臺(tái)來(lái)說(shuō)Vue增加了開(kāi)發(fā)人員的學(xué)習(xí)成本、兼容性、美觀(guān)等方面的調(diào)試成本,開(kāi)發(fā)周期偏長(zhǎng),至于是否適合管理品臺(tái)開(kāi)發(fā)就……;
綜上分析,對(duì)于管理平臺(tái)開(kāi)發(fā)建議選用easyUI或基于bootstrap搭建好的管理平臺(tái),本文選擇基于bootstrap的管理平臺(tái)進(jìn)行說(shuō)明。
UI選取
經(jīng)過(guò)調(diào)研,選取了一套業(yè)內(nèi)好評(píng)率較高的UI(ace-master),
Ace是一個(gè)基于Twitter bootstrap3開(kāi)發(fā)的后臺(tái)模板。
GitHub Ace地址:https://github.com/bopoda/ace
Ace演示:http://ace.jeka.by/
主體界面如下:
此框架功能多多,詳細(xì)功能請(qǐng)看演示。
系統(tǒng)實(shí)現(xiàn)
實(shí)現(xiàn)效果
登錄
2)首頁(yè)
3)以下是權(quán)限管理的具體模塊
開(kāi)發(fā)規(guī)范
下圖為框架的三個(gè)區(qū)域,其中主面板區(qū)域采用為一個(gè)div(沒(méi)有采用iframe設(shè)計(jì)),每個(gè)菜單的內(nèi)容均會(huì)更新主面板區(qū)域,故在主面板區(qū)域內(nèi)容需要遵循一定的規(guī)范:
建議每個(gè)一級(jí)菜單在一個(gè)包中,每個(gè)包中的二級(jí)菜單均為一個(gè)單獨(dú)的控制器。建議頁(yè)面也需按同樣方式設(shè)計(jì)。每個(gè)頁(yè)面中的字段必須全局唯一(very import)
每個(gè)頁(yè)面中的字段可采用駝峰式也可用下劃線(xiàn)式,但必須確保每個(gè)頁(yè)面以及下面多級(jí)頁(yè)面中的每個(gè)字段名必須不同(即使業(yè)務(wù)上為同一張表的同一個(gè)字段),不可在模態(tài)框與主面板區(qū)用同一個(gè)頁(yè)面。(如此設(shè)計(jì)的原因是:由于主頁(yè)面采用div設(shè)計(jì),故為防止js檢測(cè)異常)
(important)由于主面板區(qū)域采用div設(shè)計(jì),父頁(yè)面(main.jsp)中已經(jīng)有了
故子頁(yè)面面不要引入這個(gè)js了(也無(wú)需引入),否則會(huì)引起密碼修改的模態(tài)框無(wú)法彈出;
如果想要引入的話(huà),請(qǐng)修改密碼修改的模態(tài)框彈出效果。
命名規(guī)范示例:
每個(gè)頁(yè)面中字段命名(包括方法名、表單字段、div等元素的id等):? 模塊名+頁(yè)面名+數(shù)據(jù)庫(kù)字段名
示例:userManageListAccountName
或者? ? user_manage_list_account_name
這樣組成了全局唯一字段,防止瀏覽器緩存導(dǎo)致的頁(yè)面插件功能異常和表單提交異常等問(wèn)題;
詳細(xì)設(shè)計(jì)
框架介紹
1)頁(yè)面布局
頁(yè)面布局見(jiàn)開(kāi)發(fā)規(guī)范中截圖,三個(gè)主要區(qū)域。
2)功能
功能上主要為權(quán)限管理和其它的項(xiàng)目相關(guān)的開(kāi)發(fā)人員自定義的菜單模塊。前后端交互采用ajax技術(shù),頁(yè)面核心的公共區(qū)域的交互在
;該文件中封裝了菜單url調(diào)用和菜單效果切花、主面板區(qū)域更新的ajax、菜單樹(shù)的動(dòng)態(tài)加載、解析、拼裝等功能。
3)權(quán)限
權(quán)限管理中包括用戶(hù)管理、菜單管理、角色管理、權(quán)限分配和密碼修改。
4)菜單加載
用戶(hù)狀態(tài)為啟用時(shí)可登錄到系統(tǒng),進(jìn)入到主板面后根據(jù)用戶(hù)對(duì)應(yīng)角色查找相應(yīng)的菜單加載到菜單區(qū)域,從而實(shí)現(xiàn)不同角色的用戶(hù)能夠看到不同的菜單權(quán)限。
5)插件
框架中整合的插件主要如下(部分):
Bootstrap-table、bootstrap-datetimepicker、jquery.gritter(右上角彈框插件)、bootstrap-treeview、bootstrap-switch、jQuery.ui(確認(rèn)框)。
其中datetimepicker樣式似乎并沒(méi)有想象中的好,需要進(jìn)一步確認(rèn)原因還是切換其它插件,如果對(duì)樣式要求不高可臨時(shí)使用,但考慮到后續(xù)擴(kuò)展,故而建議盡快確認(rèn)(修復(fù)or更換)。
數(shù)據(jù)庫(kù)設(shè)計(jì)
數(shù)據(jù)庫(kù)中權(quán)限管理模塊設(shè)計(jì)了用戶(hù)表、角色表、菜單表、用戶(hù)角色關(guān)聯(lián)表、角色菜單關(guān)聯(lián)表,共計(jì)5張表,sql代碼詳見(jiàn)數(shù)據(jù)庫(kù)文件。
用戶(hù)表:
角色表:
菜單表:
用戶(hù)角色關(guān)聯(lián)表:
角色菜單關(guān)聯(lián)表:
菜單管理
菜單包括主頁(yè)面菜單區(qū)域的菜單也包含“權(quán)限管理à菜單管理”中的菜單。
1)主頁(yè)菜單封裝:
菜單表設(shè)計(jì),見(jiàn)數(shù)據(jù)庫(kù)設(shè)計(jì)。
菜單最大設(shè)計(jì)四級(jí)菜單,拼裝的json格式(下文為大致示例,以實(shí)際為準(zhǔn));
讀取庫(kù)中菜單信息,拼接采用何種算法?
方案一:循環(huán)遍歷,多重循環(huán)遍歷
方案二:遞歸
此處選擇遞歸,原因一是效率高(內(nèi)存需要或許也高,完全可容忍),二是不受限于菜單級(jí)別,
遞歸核心代碼如下(詳見(jiàn)源碼)
/**
* 遞歸查找子菜單
* @param id
* @param rootMenu
* @return
*/
private List getChilds(Long id, List rootMenu){
// 子菜單
List childList = new ArrayList();
Iterator it = rootMenu.iterator();
while(it.hasNext()) {
SysMenu menu = it.next();
// 遍歷所有節(jié)點(diǎn),將父菜單id與傳過(guò)來(lái)的id比較
if (String.valueOf(menu.getLong("menu_pa_id")).equals(String.valueOf(id))){
Map mapcc = new HashMap();
mapcc.put("id", menu.getLong("id"));
mapcc.put("menu_name", menu.getStr("menu_name"));
mapcc.put("menu_url", menu.getStr("menu_url"));
childList.add(mapcc);
it.remove();
}
}
// 把子菜單的子菜單再循環(huán)一遍
for (Map map : childList) {
//遞歸
map.put("childMenus", getChilds(Long.parseLong(map.get("id").toString()), rootMenu));
}
//遞歸退出條件
if (childList.size() == 0) {
return null;
}
return childList;
}
拼接得到j(luò)son菜單格式為(如下為二級(jí)菜單示例,其它詳見(jiàn)源碼、界面操作):
{
"status":"200",
"data":[
{
"id":1,
"childMenus":null,
"menu_url":"/manage/systemInfo.do",
"menu_name":"系統(tǒng)信息"
},
{
"id":2,
"childMenus":[
{
"id":5,
"childMenus":null,
"menu_url":"/redis/main.do",
"menu_name":"查詢(xún)r(jià)edis"
},
{
"id":6,
"childMenus":null,
"menu_url":"/redis/writeRdisPage.do",
"menu_name":"寫(xiě)redis"
}
],
"menu_url":null,
"menu_name":"redis管理"
},
{
"id":3,
"childMenus":[
{
"id":7,
"childMenus":null,
"menu_url":null,
"menu_name":"榴蓮短視頻"
},
{
"id":8,
"childMenus":null,
"menu_url":"/haohuolab/haohuoPage.do",
"menu_name":"東龍實(shí)驗(yàn)室"
}
],
"menu_url":null,
"menu_name":"東龍實(shí)驗(yàn)室"
},
{
"id":4,
"childMenus":[
{
"id":9,
"childMenus":null,
"menu_url":"/system/users/userPages.do",
"menu_name":"用戶(hù)管理"
},
{
"id":10,
"childMenus":null,
"menu_url":null,
"menu_name":"角色管理"
},
{
"id":11,
"childMenus":null,
"menu_url":null,
"menu_name":"權(quán)限分配"
},
{
"id":12,
"childMenus":null,
"menu_url":null,
"menu_name":"菜單管理"
},
{
"id":13,
"childMenus":null,
"menu_url":"/manage/updatePwdPages.do",
"menu_name":"密碼修改"
}
],
"menu_url":null,
"menu_name":"權(quán)限管理"
}
],
"msg":"success"
}
2)菜單解析
上面是拼接菜單代碼,下面是解析菜單代碼:
解析菜單的時(shí)候踩了一個(gè)坑,就是二級(jí)菜單在瀏覽器端始終無(wú)法打開(kāi),反復(fù)調(diào)試到晚上十一二點(diǎn)始終不知道什么原因,第二天來(lái)了之后繼續(xù)調(diào)試,最終發(fā)現(xiàn)是a標(biāo)簽上缺少了一個(gè)屬性(class='dropdown-toggle'),有時(shí)可能就是很小的一個(gè)問(wèn)題讓你耽誤很長(zhǎng)很長(zhǎng)的時(shí)間還弄的自己焦頭爛額,深感有時(shí)阻礙你前進(jìn)的可能不是那萬(wàn)里征程(搭建整套完善框架),卻可能是腳下的一粒沙子。
廢話(huà)少說(shuō),直接上遞歸核心代碼(實(shí)際略有改動(dòng),詳見(jiàn)源碼):
/**
* 遞歸遍歷子樹(shù)
* @param list
*/
function mainPageRecurSubTree(ctx,list){
if(null==list || ""==list || "null"==list){
return "";
}
var mainPageRecurSubTreeStr = "";
mainPageRecurSubTreeStr +=
"
for(var m=0;m
var menuSub = list[m];
mainPageRecurSubTreeStr +=
"
"+""+
""+
menuSub.menu_name;
if(null!=menuSub.childMenus && ""!=menuSub.childMenus && "null"!=menuSub.childMenus){
mainPageRecurSubTreeStr +=
"";
}
mainPageRecurSubTreeStr +=
""+
""+
mainPageRecurSubTree(ctx,menuSub.childMenus)+
"";
}
mainPageRecurSubTreeStr +=
"
";return mainPageRecurSubTreeStr;
}
3)權(quán)限管理/菜單管理
菜單插件采用bootstrap-treeview插件,
開(kāi)關(guān)按鈕采用bootstrap-switch插件;注意:將所需的開(kāi)關(guān)插件放入到main.jsp中,開(kāi)關(guān)樣式方可正常引用,否則如果放到每個(gè)功能模塊的子頁(yè)面中會(huì)導(dǎo)致插件無(wú)法完全加載而導(dǎo)致的樣式顯示的問(wèn)題。
菜單管理頁(yè)面中添加根菜單,也可添加子菜單,選擇/修改菜單的上級(jí)菜單,修改菜單信息等功能。
權(quán)限管理/角色管理
權(quán)限管理à角色管理:
角色管理中的菜單權(quán)限修改(修改角色對(duì)應(yīng)的菜單信息):
也采用了bootstrap-TreeView插件,但是此原生的樹(shù)菜單沒(méi)有級(jí)聯(lián)選項(xiàng),故添加級(jí)聯(lián)選擇的js,核心代碼如下:
//級(jí)聯(lián)選擇:選中
$("#roleManageUpdateRoleMenuAllTreeMes").on('nodeChecked',function(event,node){
roleManageUpdateRoleMenuNodeChecked(event, node);;
});
//級(jí)聯(lián)選擇:取消選中
$("#roleManageUpdateRoleMenuAllTreeMes").on('nodeUnchecked',function(event,node){
roleManageUpdateRoleMenuNodeUnchecked(event, node);;
});
//如下是響應(yīng)菜單選中和取消選中的操作
var roleManageUpdateRoleMenuNodeCheckedSilent = false;
function roleManageUpdateRoleMenuNodeChecked(event, node){
if(roleManageUpdateRoleMenuNodeCheckedSilent){
return;
}
roleManageUpdateRoleMenuNodeCheckedSilent = true;
roleManageUpdateRoleMenuCheckAllParent(node);
roleManageUdpateRoleMenuCheckAllSon(node);
roleManageUpdateRoleMenuNodeCheckedSilent = false;
}
var roleManageUpdateRoleMenuNodeUncheckedSilent = false;
function roleManageUpdateRoleMenuNodeUnchecked(event, node){
if(roleManageUpdateRoleMenuNodeUncheckedSilent){
return;
}
roleManageUpdateRoleMenuNodeUncheckedSilent = true;
roleManageUpdateRoleMenuUncheckAllParent(node);
roleManageUpdateRoleMenuUncheckAllSon(node);
roleManageUpdateRoleMenuNodeUncheckedSilent = false;
}
//選中全部父節(jié)點(diǎn)
function roleManageUpdateRoleMenuCheckAllParent(node){
$("#roleManageUpdateRoleMenuAllTreeMes").treeview('checkNode',node.nodeId,{silent:true});
var parentNode = $("#roleManageUpdateRoleMenuAllTreeMes").treeview('getParent',node.nodeId);
if(!("nodeId" in parentNode)){
return;
}else{
roleManageUpdateRoleMenuCheckAllParent(parentNode);
}
}
//取消全部父節(jié)點(diǎn)
function roleManageUpdateRoleMenuUncheckAllParent(node){
$("#roleManageUpdateRoleMenuAllTreeMes").treeview('uncheckNode',node.nodeId,{silent:true});
var siblings = $("#roleManageUpdateRoleMenuAllTreeMes").treeview('getSiblings', node.nodeId);
var parentNode = $("#roleManageUpdateRoleMenuAllTreeMes").treeview('getParent',node.nodeId);
if(!("nodeId" in parentNode)) {
return;
}
var isAllUnchecked = true;? //是否全部沒(méi)選中
for(var i in siblings){
if(siblings[i].state.checked){
isAllUnchecked=false;
break;
}
}
if(isAllUnchecked){
roleManageUpdateRoleMenuUncheckAllParent(parentNode);
}
}
//級(jí)聯(lián)選中所有子節(jié)點(diǎn)
function roleManageUdpateRoleMenuCheckAllSon(node){
$("#roleManageUpdateRoleMenuAllTreeMes").treeview('checkNode',node.nodeId,{silent:true});
if(node.nodes!=null&&node.nodes.length>0){
for(var i in node.nodes){
roleManageUdpateRoleMenuCheckAllSon(node.nodes[i]);
}
}
}
//級(jí)聯(lián)取消所有子節(jié)點(diǎn)
function roleManageUpdateRoleMenuUncheckAllSon(node){
$("#roleManageUpdateRoleMenuAllTreeMes").treeview('uncheckNode',node.nodeId,{silent:true});
if(node.nodes!=null&&node.nodes.length>0){
for(var i in node.nodes){
roleManageUpdateRoleMenuUncheckAllSon(node.nodes[i]);
}
}
}
權(quán)限管理/權(quán)限分配
權(quán)限管理à權(quán)限分配:為不同用戶(hù)分配不同角色。
在權(quán)限分配è角色分配? 頁(yè)面中,使用了一個(gè)多選框的插件(用于選擇多個(gè)角色),如下圖:
在使用中發(fā)現(xiàn)這個(gè)選擇框第一次打開(kāi)時(shí)正常,之后再打開(kāi)始終不正常,調(diào)試發(fā)現(xiàn)是因?yàn)閟elect中動(dòng)態(tài)添加了一個(gè)div并且這個(gè)div的style=“width:0px”;導(dǎo)致select的展示出現(xiàn)問(wèn)題。試了各種方式,網(wǎng)上搜了各種方案均失敗。最終萬(wàn)般無(wú)奈之下猜想可能是引用的js文件中生成這個(gè)內(nèi)部div時(shí)導(dǎo)致寬度獲取的問(wèn)題,于是便修改引用的js源碼,修改如下:
至此問(wèn)題解決。
問(wèn):如何知道要修改這個(gè)寬度(如何定位到是要修改這個(gè)寬度的)?
答:在瀏覽器中調(diào)試時(shí)發(fā)現(xiàn)在select中生成的div的id是在select的id的基礎(chǔ)之上添加了“_chosen”,于是搜索“_chosen”發(fā)現(xiàn)整個(gè)js源碼中只有一個(gè)“_chosen”,于是在此附近尋找width相關(guān)的代碼,終于發(fā)現(xiàn)了并嘗試修改成功。
權(quán)限管理/用戶(hù)管理
權(quán)限管理à用戶(hù)管理:功能為對(duì)能夠登錄到系統(tǒng)的管理用戶(hù)的增、查、修改、停用操作。
此頁(yè)面中的table采用bootstrap原生表格,增改查的邏輯完全為自己實(shí)現(xiàn)。沒(méi)有使用bootstrap-table插件。
本系統(tǒng)設(shè)計(jì)者建議使用bootstrap-table插件(why? 我也不知道,就是感覺(jué)成熟開(kāi)源的業(yè)內(nèi)小有名氣的東東一定比自己寫(xiě)的好),插件demo見(jiàn)系統(tǒng)demo示例。
此模塊中的用戶(hù)為系統(tǒng)的管理人員。
延伸思考
Iframe為子頁(yè)面,可不受父頁(yè)面干擾,但是究竟用還是不用好,有待深思的問(wèn)題;bootstrap-switch boostrap的開(kāi)關(guān)按鈕插件并未能初始化開(kāi)或者關(guān)狀態(tài),此功能關(guān)乎開(kāi)關(guān)的美觀(guān),需探究如何修改或選用其它插件待進(jìn)一步深思。
3)系統(tǒng)待優(yōu)化之處:
權(quán)限訪(fǎng)問(wèn)控制該如何優(yōu)化(內(nèi)存?redis?)
Mybatis整合
嚴(yán)格的mvc設(shè)計(jì)模式
致謝!
初級(jí)入門(mén):澤宇、老申、昊總
問(wèn)題修復(fù):金鳳
問(wèn)題修復(fù):系統(tǒng)參與的全體java同仁
開(kāi)發(fā)者:戰(zhàn)神,彭玉,ylz,東龍;
零碎不重要的整理工作(高大上的名字:秘書(shū)):本人。
向以上四位開(kāi)發(fā)者致敬!
文檔說(shuō)明
本文檔由四位開(kāi)發(fā)者在開(kāi)發(fā)過(guò)程中心得記錄,由秘書(shū)整理匯總而成。最終解釋權(quán)歸四位開(kāi)發(fā)者所有。
參考文獻(xiàn)
https://blog.csdn.net/weixin_41981080/article/details/81912941
文末福利:
想要與大家一起交流,可進(jìn)企鵝群:589847567
群共享文件中有源碼下載。
說(shuō)明:該系統(tǒng)由以上四位開(kāi)發(fā)者在工作之余抽時(shí)間分工開(kāi)發(fā)完成,因工作較忙,時(shí)間有限等原因,系統(tǒng)中難免有瑕疵不足之處需進(jìn)一步完善,望大家諒解,在后續(xù)版本中我們會(huì)不斷完善。同時(shí)誠(chéng)邀大才雄心的有志之士加入我們共同開(kāi)發(fā)。
總結(jié)
以上是生活随笔為你收集整理的bootstrap加载mysql数据库_bootstrap后台管理系统前后台实现(含数据库)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux环境下安装多个任意版本的pyt
- 下一篇: 删除一个无头单链表的非尾节点(C语言)