感覺自己好久好久好久沒有寫文章了,突然不知道寫什麼。最近一直在忙著「醫院的HIS系統」,綜合體驗下來,就是想罵人,想暴粗口。
產品:「你就說,能不能做吧!是能做呢,還是不能做呢。」
產品:「先做出來看看!怎麼實現是你的問題。」
產品:「這個需求很簡單吧!用xxx就能搞定了。」
產品:「這個需求老闆同意了!你照做就好了。」
吸氣......呼氣......吸氣......呼氣......但是也實在忍受不了,已經很心軟的評估出來2個人需要176天的工作量,硬是要人家一個月內完成。吸氣......呼氣......吸氣......呼氣......爆粗口真心對美少女形象不好,姐姐我是一個有氣質的程序媛。
今晚山竹颱風天,既然放假不加班,趕緊趁著這會頭腦清醒,心情不錯,敲幾行代碼先,也不能算是乾貨,這個「用戶許可權角色管理系統」如標題版一樣,是個超級簡易版本,但是後續會出高級版本的,放心~~因為知識是屬於自己的,所以不管怎樣,多積累一些乾貨總沒錯,至少從某種程度上來說,自信心或多或少會增強。
//載入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) } })
簡易版本忽略了「排序」「資源類別(是否菜單,是否功能)」「狀態(禁用,啟用)」等欄位,懶得寫了,之後再添加進去好了。
//載入資料庫模塊 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)
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)
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)
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)
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)
既然表建好了,模型也暴露出來了,那麼我們可以開始寫【頁面】和【介面】了
<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 推薦閱讀: