[簡易版node+mongo][後臺1]使用者許可權角色管理後臺
感覺自己好久好久好久沒有寫文章了,突然不知道寫什麼。最近一直在忙著“醫院的HIS系統”,綜合體驗下來,就是想罵人,想暴粗口。
產品:“
你就說,能不能做吧!是能做呢,還是不能做呢。
”
產品:“
先做出來看看!怎麼實現是你的問題。
”
產品:“
這個需求很簡單吧!用xxx就能搞定了。
”
產品:“
這個需求老闆同意了!你照做就好了。
”
吸氣……呼氣……吸氣……呼氣……但是也實在忍受不了,已經很心軟的評估出來2個人需要176天的工作量,硬是要人家一個月內完成。吸氣……呼氣……吸氣……呼氣……爆粗口真心對美少女形象不好,姐姐我是一個有氣質的程式媛。
【頁面預覽】
哈哈,所有頁面都在一塊,方便
【目錄】
今晚山竹颱風天,既然放假不加班,趕緊趁著這會頭腦清醒,心情不錯,敲幾行程式碼先,也不能算是乾貨,這個“使用者許可權角色管理系統”如標題版一樣,是個超級簡易版本,
但是後續會出高階版本的
,放心~~因為知識是屬於自己的,所以不管怎樣,多積累一些乾貨總沒錯,至少從某種程度上來說,自信心或多或少會增強。
【app。js入口檔案】
//載入express模組,建立web應用
var
express
=
require
(
‘express’
)
//建立app應用 => NodeJS Http。createServer()
var
app
=
express
()
//載入模板處理模組 => 後端邏輯和頁面表現分離,即前後端分離
var
swig
=
require
(
‘swig’
)
//設定模板檔案存放的目錄
app
。
set
(
‘views’
,
‘。/src/views’
)
//配置應用模板,定義當前應用使用的模板引擎
app
。
engine
(
‘html’
,
swig
。
renderFile
)
//註冊所使用的模板引擎,將模板新增到app應用內
app
。
set
(
‘view engine’
,
‘html’
)
//設定靜態檔案託管
app
。
use
(
‘/media’
,
express
。
static
(
__dirname
+
‘/src/views/media’
))
//載入body-parser中介軟體,用來處理post提交過來的資料
var
bodyParser
=
require
(
‘body-parser’
)
//配置bodyParser中介軟體,urlencoded會自動在請求中的request物件增加一個屬性body
app
。
use
(
bodyParser
。
urlencoded
({
extended
:
true
}))
app
。
use
(
bodyParser
。
json
())
//根據不同的功能劃分模組,預設js檔案,相當於app。get(url, cb)
app
。
use
(
‘/user’
,
require
(
‘。/src/route/user’
))
app
。
use
(
‘/functions’
,
require
(
‘。/src/route/functions’
))
app
。
use
(
‘/role’
,
require
(
‘。/src/route/role’
))
//連線資料庫,連線之前先安裝並開啟資料庫伺服器
var
mongoose
=
require
(
‘mongoose’
)
mongoose
。
connect
(
‘mongodb://localhost/auth-role’
,
err
=>
{
if
(
err
)
{
console
。
log
(
‘mongoose connect fail’
)
}
else
{
console
。
log
(
‘mongoose connect success’
)
var
port
=
process
。
env
。
PORT
||
3001
//監聽http請求
app
。
listen
(
port
)
console
。
log
(
‘port open at http://localhost:’
+
port
)
}
})
【entity/Function。js】
許可權表
簡易版本忽略了“排序”“資源類別(是否選單,是否功能)”“狀態(禁用,啟用)”等欄位,懶得寫了,之後再新增進去好了。
//載入資料庫模組
var
mongoose
=
require
(
‘mongoose’
)
//定義許可權表結構
var
FunctionsSchema
=
new
mongoose
。
Schema
({
name
:
String
,
//許可權名
parentId
:
{
//上級許可權的_id
type
:
String
,
default
:
0
},
location
:
String
//許可權的資源地址,用於選單跳轉頁面
},
{
versionKey
:
false
//查詢資料庫時,忽略 _v 的欄位返回
})
//為模式新增靜態方法,不會與資料庫進行互動,只有在模型例項化編譯後產生作用
//PS:透過模型調取
FunctionsSchema
。
statics
=
{
findAll
:
function
()
{
return
this
。
find
()
},
findOneById
:
function
(
id
)
{
return
this
。
findOne
({
_id
:
id
})
},
save
:
function
(
opts
)
{
return
this
。
create
(
opts
)
},
updateById
:
function
(
id
,
opts
)
{
return
this
。
update
({
_id
:
id
},
opts
)。
then
(
rs
=>
{
if
(
rs
。
ok
)
{
return
Promise
。
resolve
()
}
else
{
return
Promise
。
reject
(
‘資料庫更新許可權dao失敗’
)
}
})
},
removeById
:
function
(
id
)
{
return
this
。
remove
({
_id
:
id
})
}
}
//編譯生成Functions模型,並將模型建構函式匯出
module
。
exports
=
mongoose
。
model
(
‘Functions’
,
FunctionsSchema
)
【entity/Role。js】
角色表
var
mongoose
=
require
(
‘mongoose’
)
//定義角色表結構
var
RoleSchema
=
new
mongoose
。
Schema
({
name
:
String
//角色名
},
{
versionKey
:
false
//查詢資料庫時,忽略 _v 的欄位返回
})
//為模式新增靜態方法,不會與資料庫進行互動,只有在模型例項化編譯後產生作用
//PS:透過模型調取
RoleSchema
。
statics
=
{
findAll
:
function
()
{
return
this
。
find
()
},
findOneById
:
function
(
id
)
{
return
this
。
findOne
({
_id
:
id
})
},
save
:
function
(
opts
)
{
return
this
。
create
(
opts
)
},
updateById
:
function
(
id
,
opts
)
{
return
this
。
update
({
_id
:
id
},
opts
)。
then
(
rs
=>
{
if
(
rs
。
ok
)
{
return
Promise
。
resolve
()
}
else
{
return
Promise
。
reject
(
‘資料庫更新角色名失敗’
)
}
})
},
removeById
:
function
(
id
)
{
return
this
。
remove
({
_id
:
id
})
}
}
//編譯生成Role模型,並將模型建構函式匯出
module
。
exports
=
mongoose
。
model
(
‘Role’
,
RoleSchema
)
【entity/RoleFunction。js】
角色許可權表
var
mongoose
=
require
(
‘mongoose’
)
//即將使用ObjectId作為欄位型別,用於實現‘關聯文件的查詢’
var
Schema
=
mongoose
。
Schema
var
ObjectId
=
Schema
。
Types
。
ObjectId
//定義角色許可權表結構
var
RoleFunctionSchema
=
new
mongoose
。
Schema
({
roleId
:
{
//關於某個角色,可以ObjectId拿到角色的其他欄位
type
:
ObjectId
,
ref
:
‘Role’
},
functionId
:
{
/關於某個許可權,可以ObjectId拿到許可權的其他欄位
type
:
ObjectId
,
ref
:
‘Functions’
}
},
{
versionKey
:
false
//查詢資料庫時,忽略 _v 的欄位返回
})
//為模式新增靜態方法,不會與資料庫進行互動,只有在模型例項化編譯後產生作用
//PS:透過模型調取
RoleFunctionSchema
。
statics
=
{
findByRoleId
:
function
(
rid
)
{
return
this
。
find
({
roleId
:
rid
})
},
getFunEntityByRoleId
:
function
(
rid
)
{
return
this
。
find
({
roleId
:
rid
},
{
roleId
:
0
,
_id
:
0
})。
populate
({
path
:
‘functionId’
,
select
:
{
name
:
1
,
parentId
:
1
,
location
:
1
}
})。
then
(
farr
=>
{
let
farray
=
farr
。
map
(
item
=>
{
return
item
。
functionId
})
return
Promise
。
resolve
(
farray
)
})。
catch
(
err
=>
{
return
Promise
。
reject
()
})
},
insert
:
function
(
rid
,
fids
)
{
if
(
fids
&&
fids
。
length
)
{
let
fidsArray
=
[]
for
(
let
i
=
0
;
i
<
fids
。
length
;
i
++
)
{
fidsArray
。
push
({
roleId
:
rid
,
functionId
:
fids
[
i
]
})
}
return
this
。
insertMany
(
fidsArray
)
}
else
{
return
Promise
。
reject
(
‘角色許可權關係未選擇’
)
}
},
removeByRoleId
:
function
(
rid
)
{
return
this
。
remove
({
roleId
:
rid
})
},
removeByFunId
:
function
(
fid
)
{
return
this
。
remove
({
functionId
:
fid
})
}
}
//編譯生成RoleFunction模型,並將模型建構函式匯出
module
。
exports
=
mongoose
。
model
(
‘RoleFunction’
,
RoleFunctionSchema
)
【entity/User。js】
使用者表
var
mongoose
=
require
(
‘mongoose’
)
//定義使用者表結構
var
UserSchema
=
new
mongoose
。
Schema
({
name
:
String
,
//使用者名稱
pwd
:
String
//密碼
},
{
versionKey
:
false
//查詢資料庫時,忽略 _v 的欄位返回
})
//為模式新增靜態方法,不會與資料庫進行互動,只有在模型例項化編譯後產生作用
//PS:透過模型調取
UserSchema
。
statics
=
{
save
:
function
(
opts
)
{
return
this
。
create
(
opts
)
},
updateById
:
function
(
id
,
opts
)
{
return
this
。
update
({
_id
:
id
},
opts
)。
then
(
rs
=>
{
if
(
rs
。
ok
)
{
return
Promise
。
resolve
()
}
else
{
return
Promise
。
reject
(
‘資料庫更新使用者名稱失敗’
)
}
})
},
removeById
:
function
(
id
)
{
return
this
。
remove
({
_id
:
id
})
},
findOneById
:
function
(
uid
)
{
return
this
。
findOne
({
_id
:
uid
})
},
findUser
:
function
(
username
,
userpwd
)
{
return
this
。
findOne
({
name
:
username
,
pwd
:
userpwd
})
},
findAll
:
function
()
{
return
this
。
find
()
}
}
//編譯生成User模型,並將模型建構函式匯出
module
。
exports
=
mongoose
。
model
(
‘User’
,
UserSchema
)
【entity/UserRole。js】
使用者角色表
var
mongoose
=
require
(
‘mongoose’
)
//即將使用ObjectId作為欄位型別,用於實現‘關聯文件的查詢’
var
Schema
=
mongoose
。
Schema
var
ObjectId
=
Schema
。
Types
。
ObjectId
//定義使用者角色表結構
var
UserRoleSchema
=
new
mongoose
。
Schema
({
userId
:
{
//關於某個使用者,可以ObjectId拿到使用者的其他欄位
type
:
ObjectId
,
ref
:
‘User’
},
roleId
:
{
//關於某個角色,可以ObjectId拿到角色的其他欄位
type
:
ObjectId
,
ref
:
‘Role’
}
},
{
versionKey
:
false
})
//為模式新增靜態方法,不會與資料庫進行互動,只有在模型例項化編譯後產生作用
//PS:透過模型調取
UserRoleSchema
。
statics
=
{
findAll
:
function
(
opts
)
{
let
ingore
=
{
_id
:
0
}
let
selPop
=
{}
if
(
opts
。
userId
)
{
ingore
。
userId
=
0
selPop
=
{
path
:
‘roleId’
,
select
:
{
name
:
1
}
}
}
if
(
opts
。
roleId
)
{
ingore
。
roleId
=
0
selPop
=
{
path
:
‘userId’
,
select
:
{
name
:
1
,
pwd
:
1
}
}
}
return
this
。
find
(
opts
,
ingore
)。
populate
(
selPop
)。
then
(
urray
=>
{
if
(
urray
。
length
)
{
urray
=
urray
。
map
(
item
=>
{
if
(
opts
。
userId
)
{
return
item
。
roleId
}
if
(
opts
。
roleId
)
{
return
item
。
userId
}
})
}
return
Promise
。
resolve
(
urray
)
})。
catch
(
err
=>
{
return
Promise
。
reject
()
})
},
insert
:
function
(
uid
,
rids
)
{
if
(
rids
&&
rids
。
length
)
{
let
ridsArray
=
[]
for
(
let
i
=
0
;
i
<
rids
。
length
;
i
++
)
{
ridsArray
。
push
({
userId
:
uid
,
roleId
:
rids
[
i
]
})
}
return
this
。
insertMany
(
ridsArray
)
}
else
{
return
Promise
。
reject
(
‘使用者角色關係未選擇’
)
}
},
removeByUserId
:
function
(
uid
)
{
return
this
。
remove
({
userId
:
uid
})
},
removeByRoleId
:
function
(
rid
)
{
return
this
。
remove
({
roleId
:
rid
})
}
}
//編譯生成UserRole模型,並將模型建構函式匯出
module
。
exports
=
mongoose
。
model
(
‘UserRole’
,
UserRoleSchema
)
【index。html】
頁面
既然表建好了,模型也暴露出來了,那麼我們可以開始寫【頁面】和【介面】了
<
html
>
<
head
>
<
script
src
=
“/media/js/jquery-1。10。1。min。js”
type
=
“text/javascript”
>
script
>
<
link
rel
=
“stylesheet”
href
=
“/media/css/demo。css”
type
=
“text/css”
>
<
link
rel
=
“stylesheet”
href
=
“/media/css/zTreeStyle/zTreeStyle。css”
type
=
“text/css”
>
<
script
type
=
“text/javascript”
src
=
“/media/js/jquery。ztree。core。js”
>
script
>
<
script
type
=
“text/javascript”
src
=
“/media/js/jquery。ztree。excheck。js”
>
script
>
<
style
>
。
loginPanel
{
padding
:
20
px
;
background-color
:
lightpink
;}
。
navPanel
{
display
:
none
;
word-break
:
break-all
;}
。
dialog
{
display
:
none
;
position
:
fixed
;
top
:
0
;
left
:
0
;
width
:
100
%
;
bottom
:
0
;
background-color
:
rgba
(
0
,
0
,
0
,
。5
)}
。
dialogContent
{
background-color
:
#fff
;
width
:
420
px
;
margin
:
50
px
;}
div
。
cursor
{
cursor
:
pointer
;
display
:
inline
-
block
;}
style
>
head
>
<
body
>
<!—— 登入面板 ——>
<
div
class
=
“loginPanel”
>
<
div
class
=
“navForm”
>
<
h1
>
Login html
h1
>
username:
<
input
type
=
“text”
name
=
“loginName”
/><
br
/>
password:
<
input
type
=
“text”
name
=
“loginPwd”
/><
br
/>
<
button
id
=
“loginBtn”
>
login now
button
>
div
>
<
div
class
=
“navPanel”
>
div
>
div
>
<
ul
>
<!—— 使用者面板 ——>
<
li
style
=
“background-color: lightblue;”
>
<
div
class
=
“tableLink”
>
使用者選單列表
div
>
<
div
class
=
“tableList”
>
<
button
onclick
=
“editUser()”
>
新增使用者
button
>
<
table
border
=
“1”
id
=
“usersTable”
>
<
thead
>
<
th
>
使用者名稱
th
><
th
>
密碼
th
><
th
>
使用者角色
<
th
>
操作
th
>
thead
>
<
tbody
>
tbody
>
table
>
div
>
li
>
<!—— 角色面板 ——>
<
li
style
=
“background-color: lightsalmon;”
>
<
div
class
=
“tableLink”
>
角色列表
div
>
<
div
class
=
“tableList”
>
<
button
onclick
=
“editRole()”
>
新增角色
button
>
<
table
border
=
“1”
id
=
“rolesTable”
>
<
thead
>
<
th
>
角色名
th
><
th
>
操作
th
>
thead
>
<
tbody
>
tbody
>
table
>
div
>
li
>
<!—— 許可權面板 ——>
<
li
style
=
“background-color: lightgreen;”
>
<
div
class
=
“tableLink”
>
許可權選單列表
div
>
<
div
class
=
“tableList”
>
<
button
onclick
=
“editAuth()”
>
新增許可權
button
>
<
table
border
=
“1”
id
=
“authsTable”
>
<
thead
>
<
th
>
名稱
th
><
th
>
資源地址或標識
th
><
th
>
父級編號
th
><
th
>
操作
th
>
thead
>
<
tbody
>
tbody
>
table
>
div
>
li
>
ul
>
<!—— 許可權【新增】【編輯】彈窗面板 ——>
<
div
class
=
“dialog”
id
=
“authDialog”
>
<
div
class
=
“dialogContent”
>
<
form
>
<
input
type
=
“hidden”
name
=
“authId”
/>
父級:
<
span
class
=
“authSelect”
>
span
><
br
/>
<
div
class
=
“zTreeDemoBackground left”
>
<
ul
id
=
“authClickTree”
class
=
“ztree”
>
ul
>
div
>
名稱:
<
input
type
=
“text”
name
=
“authName”
/><
br
/>
資源地址:
<
input
type
=
“text”
name
=
“authUrl”
/>
form
>
<
div
style
=
“text-align: center;margin-top: 20px;”
>
<
button
class
=
“authDialogConfirmBtn”
>
confirm
button
>
<
button
class
=
“dialogCancelBtn”
>
cancel
button
>
div
>
div
>
div
>
<!—— 使用者【新增】【編輯】彈窗面板 ——>
<
div
class
=
“dialog”
id
=
“userDialog”
>
<
div
class
=
“dialogContent”
>
<
form
>
<
input
type
=
“hidden”
name
=
“userId”
/>
姓名:
<
input
type
=
“text”
name
=
“userName”
/><
br
/>
密碼:
<
input
type
=
“text”
name
=
“userPwd”
/><
br
/>
角色:
<
div
class
=
“roleCheckbox”
>
div
>
form
>
<
div
style
=
“text-align: center;margin-top: 20px;”
>
<
button
class
=
“userDialogConfirmBtn”
>
confirm
button
>
<
button
class
=
“dialogCancelBtn”
>
cancel
button
>
div
>
div
>
div
>
<!—— 角色【新增】【編輯】彈窗面板 ——>
<
div
class
=
“dialog”
id
=
“roleDialog”
>
<
div
class
=
“dialogContent”
>
<
form
>
<
input
type
=
“hidden”
name
=
“roleId”
/>
角色名:
<
input
type
=
“text”
name
=
“roleName”
/><
br
/>
分配的許可權:
<
div
class
=
“zTreeDemoBackground left”
>
<
ul
id
=
“roleAuthCheckboxTree”
class
=
“ztree”
>
ul
>
div
>
form
>
<
div
style
=
“text-align: center;margin-top: 20px;”
>
<
button
class
=
“roleDialogConfirmBtn”
>
confirm
button
>
<
button
class
=
“dialogCancelBtn”
>
cancel
button
>
div
>
div
>
div
>
body
>
html
>
俗話說的好
【萬事開頭難】
,打好基礎很重要
所謂的使用者許可權角色後臺最底層的基礎,其實是許可權,因此第一步,應該先去實現“許可權的增刪改查”,lets go !
【快速入口】