感覺自己好久好久好久沒有寫文章了,突然不知道寫什麼。最近一直在忙著「醫院的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: 20px;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: 420px;margin: 50px;}
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 !

【快速入口】

我不是天使:[簡易版node+mongo][許可權2]用戶許可權角色管理後台?

zhuanlan.zhihu.com圖標我不是天使:[簡易版node+mongo][角色3]用戶許可權角色管理後台?

zhuanlan.zhihu.com
圖標
我不是天使:[簡易版node+mongo][用戶4]用戶許可權角色管理後台?

zhuanlan.zhihu.com
圖標

推薦閱讀:

相关文章